diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2015-09-29 13:35:50 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2015-09-29 13:35:50 -0400 |
| commit | 4e4d470626087c26ee18f5cb04c86647b5f2699c (patch) | |
| tree | 869a5c7452c50b1e751d86e7058d090f3d55f69b /BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java | |
| parent | 47577a40bc0e298041ab0915fa4bdc3355d53349 (diff) | |
Added random grammar support.
Import of library code from version 1 finished. Now for more library
code and examples on library usage.
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java')
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java new file mode 100644 index 0000000..8733723 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java @@ -0,0 +1,177 @@ +package bjc.utils.gen; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.function.Function; + +import bjc.utils.funcdata.FunctionalList; + +/** + * A random grammar, where certain rules will come up morre often than + * others. + * + * @author ben + * + * @param <E> The values that make up sentances of this grammar. + */ +public class WeightedGrammar<E> { + protected Map<E, WeightedRandom<FunctionalList<E>>> rules; + protected Map<E, WeightedGrammar<E>> subgrammars; + private Random sr; + + /** + * Create a new weighted grammar that uses the specified source of randomness. + */ + public WeightedGrammar(Random src) { + this(); + sr = src; + } + + /** + * Create a new weighted grammar. + */ + public WeightedGrammar() { + rules = new HashMap<>(); + } + + /** + * Add a case to an already existing rule. + * + * @param rule The rule to add a case to. + * @param prob The probability for this rule to be chosen. + * @param cse The case being added. + */ + public void addCase(E rule, int prob, FunctionalList<E> cse) { + WeightedRandom<FunctionalList<E>> rn = rules.get(rule); + + rn.addProb(prob, cse); + } + + /** + * Add a new rule with no cases. + * @param name The name of the rule to add. + * @return Whether or not the rule was succesfully added. + */ + public boolean addRule(E name) { + if(sr == null) { + sr = new Random(); + } + return addRule(name, new WeightedRandom<>(sr)); + } + + /** + * Add a new rule with a set of cases. + * @param name The name of the rule to add. + * @param rnd The set of cases for the rule. + * @return Whether or not the rule was succesfully added. + */ + public boolean addRule(E name, WeightedRandom<FunctionalList<E>> rnd) { + if (rules.containsKey(name)) { + return false; + } else { + rules.put(name, rnd); + return true; + } + } + + /** + * Add a subgrammar. + * @param name The name of the subgrammar. + * @param subG The subgrammar to add. + * @return Whether or not the subgrammar was succesfully added. + */ + public boolean addSubGrammar(E name, WeightedGrammar<E> subG) { + if (subgrammars.containsKey(name)) { + return false; + } else { + subgrammars.put(name, subG); + return true; + } + } + + /** + * Generate a set of debug sentences for the specified rule. + * Only generates sentances one layer deep. + * @param rl The rule to test. + * @return A set of sentances generated by the specified rule. + */ + public FunctionalList<FunctionalList<E>> debugVals(E rl) { + FunctionalList<FunctionalList<E>> fl = new FunctionalList<>(); + + WeightedRandom<FunctionalList<E>> random = rules.get(rl); + + for (int i = 0; i < 10; i++) { + fl.add(random.genVal()); + } + + return fl; + } + + /** + * Generate a generic sentance from a initial rule. + * + * @param initRule The initial rule to start with. + * @param f The function to transform grammar output into something. + * @param spacer The spacer element to add in between output tokens. + * @return A randomly generated sentance from the specified initial rule. + */ + public <T> FunctionalList<T> genGeneric(E initRule, Function<E, T> f, + T spacer) { + FunctionalList<T> r = new FunctionalList<>(); + + if (subgrammars.containsKey(initRule)) { + subgrammars.get(initRule).genGeneric(initRule, f, spacer) + .forEach(rp -> { + r.add(rp); + r.add(spacer); + }); + } else if (rules.containsKey(initRule)) { + rules.get(initRule).genVal().forEach( + rp -> genGeneric(rp, f, spacer).forEach(rp2 -> { + r.add(rp2); + r.add(spacer); + })); + } else { + r.add(f.apply(initRule)); + r.add(spacer); + } + + return r; + } + + /** + * Generate a random list of grammar elements from a given initial rule. + * @param initRule The initial rule to start with. + * @param spacer The item to use to space the list. + * @return A list of random grammar elements generated by the specified rule. + */ + public FunctionalList<E> genList(E initRule, E spacer) { + return genGeneric(initRule, s -> s, spacer); + } + + /** + * Get the subgrammar with the specified name. + * @param name The name of the subgrammar to get. + * @return The subgrammar with the specified name. + */ + public WeightedGrammar<E> getSubGrammar(E name) { + return subgrammars.get(name); + } + + /** + * Remove a rule with the specified name. + * @param name The name of the rule to remove. + */ + public void removeRule(E name) { + rules.remove(name); + } + + /** + * Remove a subgrammar with the specified name. + * @param name The name of the subgrammar to remove. + */ + public void removeSubgrammar(E name) { + subgrammars.remove(name); + } +} |
