From 4e4d470626087c26ee18f5cb04c86647b5f2699c Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Tue, 29 Sep 2015 13:35:50 -0400 Subject: Added random grammar support. Import of library code from version 1 finished. Now for more library code and examples on library usage. --- .../main/java/bjc/utils/gen/WeightedGrammar.java | 177 +++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java (limited to 'BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java') 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 The values that make up sentances of this grammar. + */ +public class WeightedGrammar { + protected Map>> rules; + protected Map> 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 cse) { + WeightedRandom> 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> 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 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> debugVals(E rl) { + FunctionalList> fl = new FunctionalList<>(); + + WeightedRandom> 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 FunctionalList genGeneric(E initRule, Function f, + T spacer) { + FunctionalList 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 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 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); + } +} -- cgit v1.2.3