From d8b3b3c5e4441cecec98c06a36fc81570008c888 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Tue, 26 Jan 2016 11:32:41 -0500 Subject: Updates to various things, and addition of a graph class. --- .../main/java/bjc/utils/gen/WeightedGrammar.java | 222 +++++++++++++++++---- 1 file changed, 187 insertions(+), 35 deletions(-) (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 index 8733723..228f14d 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java @@ -1,46 +1,55 @@ package bjc.utils.gen; -import java.util.HashMap; +import java.util.Hashtable; import java.util.Map; import java.util.Random; +import java.util.Set; import java.util.function.Function; +import bjc.utils.data.Pair; import bjc.utils.funcdata.FunctionalList; /** - * A random grammar, where certain rules will come up morre often than + * A random grammar, where certain rules will come up more often than * others. * * @author ben * - * @param The values that make up sentances of this grammar. + * @param + * The values that make up sentances of this grammar. */ public class WeightedGrammar { + protected String initRule; protected Map>> rules; + private Random sr; protected Map> subgrammars; - private Random sr; /** - * Create a new weighted grammar that uses the specified source of randomness. + * Create a new weighted grammar. */ - public WeightedGrammar(Random src) { - this(); - sr = src; + public WeightedGrammar() { + rules = new Hashtable<>(); + subgrammars = new Hashtable<>(); } - + /** - * Create a new weighted grammar. + * Create a new weighted grammar that uses the specified source of + * randomness. */ - public WeightedGrammar() { - rules = new HashMap<>(); + public WeightedGrammar(Random src) { + this(); + sr = src; } /** * 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. + * @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); @@ -48,13 +57,28 @@ public class WeightedGrammar { rn.addProb(prob, cse); } + public boolean addGrammarAlias(E name, E alias) { + if (subgrammars.containsKey(alias)) { + return false; + } else { + if (subgrammars.containsKey(name)) { + subgrammars.put(alias, subgrammars.get(name)); + return true; + } else { + return false; + } + } + } + /** * Add a new rule with no cases. - * @param name The name of the rule to add. + * + * @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) { + if (sr == null) { sr = new Random(); } return addRule(name, new WeightedRandom<>(sr)); @@ -62,8 +86,11 @@ public class WeightedGrammar { /** * 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. + * + * @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) { @@ -77,8 +104,11 @@ public class WeightedGrammar { /** * Add a subgrammar. - * @param name The name of the subgrammar. - * @param subG The subgrammar to add. + * + * @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) { @@ -91,9 +121,11 @@ public class WeightedGrammar { } /** - * Generate a set of debug sentences for the specified rule. - * Only generates sentances one layer deep. - * @param rl The rule to test. + * 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) { @@ -111,10 +143,14 @@ public class WeightedGrammar { /** * 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. + * @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) { @@ -141,27 +177,98 @@ public class WeightedGrammar { } /** - * 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. + * 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); } + public String getInitRule() { + return initRule; + } + /** * Get the subgrammar with the specified name. - * @param name The name of the subgrammar to get. + * + * @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); } + /** + * Create a series of alternatives for a rule by prefixing them with a + * given token + * + * @param addProb + * The amount to adjust the probability by + * @param rName + * The name of the rule to prefix + * @param prefixToken + * The token to prefix to the rule + */ + public void prefixRule(E rName, E prefixToken, int addProb) { + WeightedRandom> rule = rules.get(rName); + + FunctionalList>> newResults = new FunctionalList<>(); + + rule.getValues().forEach((par) -> { + FunctionalList nl = par.r.clone(); + nl.prepend(prefixToken); + + newResults.add(new Pair<>(par.l + addProb, nl)); + }); + + newResults.forEach((par) -> { + addCase(rName, par.l, par.r); + }); + } + + public void multiPrefixRule(E rName, E prefixToken, int addProb, + int nTimes) { + WeightedRandom> rule = rules.get(rName); + + FunctionalList>> newResults = new FunctionalList<>(); + + rule.getValues().forEach((par) -> { + FunctionalList> nls = new FunctionalList<>(); + + // TODO bugtest this. if it works, write multiSuffixWith + for (int i = 1; i <= nTimes; i++) { + FunctionalList nl = par.r.clone(); + + for (int j = 1; j <= i; j++) { + nl.prepend(prefixToken); + } + + nls.add(nl); + } + + nls.forEach((ls) -> { + newResults.add(new Pair<>(par.l + addProb, ls)); + }); + }); + + newResults.forEach((par) -> { + addCase(rName, par.l, par.r); + }); + } + /** * Remove a rule with the specified name. - * @param name The name of the rule to remove. + * + * @param name + * The name of the rule to remove. */ public void removeRule(E name) { rules.remove(name); @@ -169,9 +276,54 @@ public class WeightedGrammar { /** * Remove a subgrammar with the specified name. - * @param name The name of the subgrammar to remove. + * + * @param name + * The name of the subgrammar to remove. */ public void removeSubgrammar(E name) { subgrammars.remove(name); } + + /** + * Returns the number of rules in this grammar + * + * @return The number of rules in this grammar + */ + public int ruleCount() { + return rules.size(); + } + + /** + * Returns a set containing all of the rules in this grammar + * + * @return The set of all rule names in this grammar + */ + public Set ruleNames() { + return rules.keySet(); + } + + public void setInitRule(String initRule) { + this.initRule = initRule; + } + + public void suffixRule(E rName, E prefixToken, int addProb) { + WeightedRandom> rule = rules.get(rName); + + FunctionalList>> newResults = new FunctionalList<>(); + + rule.getValues().forEach((par) -> { + FunctionalList nl = par.r.clone(); + nl.add(prefixToken); + + newResults.add(new Pair<>(par.l + addProb, nl)); + }); + + newResults.forEach((par) -> { + addCase(rName, par.l, par.r); + }); + } + + public boolean hasInitRule() { + return initRule != null && !initRule.equalsIgnoreCase(""); + } } -- cgit v1.2.3