public ImmutableSentenceDomainModel(ISentenceFormModel formModel, IDictionary<ISentenceForm, ISentenceFormDomain> domains) : base(ImmutableSentenceFormModel.CopyOf(formModel)) { //if (!formModel.SentenceForms.SetEquals(domains.Keys)) // throw new Exception(); _domains = domains.ToImmutableDictionary(); }
/// <summary> /// Returns an ImmutableSentenceFormModel with the same contents as the given SentenceFormModel. /// May not actually create a copy if the input is immutable. /// </summary> /// <param name="other"></param> /// <returns></returns> public static ImmutableSentenceFormModel CopyOf(ISentenceFormModel other) { var immutableSentenceDomainModel = other as ImmutableSentenceDomainModel; if (immutableSentenceDomainModel != null) return CopyOf(immutableSentenceDomainModel.FormModel); var immutableSentenceFormModel = other as ImmutableSentenceFormModel; if (immutableSentenceFormModel != null) return immutableSentenceFormModel; var rulesByForm = new MultiDictionary<ISentenceForm, Implication>(false); var trueSentencesByForm = new MultiDictionary<ISentenceForm, Fact>(false); foreach (ISentenceForm form in other.SentenceForms) { rulesByForm[form] = other.GetRules(form); trueSentencesByForm[form] = other.GetSentencesListedAsTrue(form); } var dependencyGraph = new MultiDictionary<ISentenceForm, ISentenceForm>(true); foreach (KeyValuePair<ISentenceForm, ICollection<ISentenceForm>> kv in other.DependencyGraph) dependencyGraph[kv.Key] = kv.Value; return new ImmutableSentenceFormModel(ImmutableList.CreateRange(other.Description), ImmutableHashSet.CreateRange(other.SentenceForms), ImmutableHashSet.CreateRange(other.ConstantSentenceForms), ImmutableHashSet.CreateRange(other.IndependentSentenceForms), dependencyGraph, rulesByForm, trueSentencesByForm); }
private static IEnumerable<Implication> ApplyAmbiguitiesForLiteral(Expression literal, Implication rule, IDictionary<ISentenceForm, ICollection<Ambiguity>> ambiguitiesByOriginalForm, ISentenceFormModel model) { var results = new List<Implication> { rule }; var varGen = new UnusedVariableGenerator(rule); var fact = literal as Fact; if (fact != null) { ISentenceForm form = model.GetSentenceForm(fact); ICollection<Ambiguity> ambiguities; if (ambiguitiesByOriginalForm.TryGetValue(form, out ambiguities)) { IEnumerable<Ambiguity> applicableAmiguities = ambiguities.Where(ambiguity => ambiguity.Applies(fact)); IEnumerable<Substitution> substitutions = applicableAmiguities.Select(ambiguity => ambiguity.GetReplacementAssignment(fact, varGen)); IEnumerable<Implication> implications = substitutions.Select(substitution => (Implication)rule.ApplySubstitution(substitution)); results.AddRange(implications); } } else if (literal is Negation) { // Do nothing. Variables must appear in a positive literal in the // rule, and will be handled there. } else if (literal is Disjunction) { throw new Exception("ORs should have been removed"); //} else if (literal is GdlDistinct) { // Do nothing } return results; }
private static List<Implication> ApplyAmbiguities(Implication originalRule, MultiDictionary<ISentenceForm, Ambiguity> ambiguitiesByOriginalForm, ISentenceFormModel model) { var rules = new List<Implication> { originalRule }; //Each literal can potentially multiply the number of rules we have, so we apply each literal separately to the entire list of rules so far. IEnumerable<Expression> originalSentences = ImmutableHashSet.Create(originalRule.Consequent).Concat(originalRule.Antecedents.Conjuncts); foreach (Expression literal in originalSentences) { var newRules = new List<Implication>(); foreach (Implication rule in rules) { Debug.Assert(originalRule.Consequent.Arity == rule.Consequent.Arity); newRules.AddRange(ApplyAmbiguitiesForLiteral(literal, rule, ambiguitiesByOriginalForm, model)); } rules = newRules; } return rules; }
public static ImmutableConstantChecker Create(ISentenceFormModel sentenceModel, MultiDictionary<ISentenceForm, Fact> sentencesByForm) { return new ImmutableConstantChecker(ImmutableSentenceFormModel.CopyOf(sentenceModel), sentencesByForm); }
/** * Precomputes the true sentences in every constant sentence form in the given * sentence model and returns the results in the form of a ConstantChecker. * * The implementation uses a forward-chaining reasoner. * * For accurate results, the rules used should have had the {@link NewVariableConstrainer} * transformation applied to them. * * On average, this approach is more efficient than {@link #createWithProver(SentenceFormModel)}. */ //public static ImmutableConstantChecker createWithForwardChaining(SentenceDomainModel model) { // GdlChainingReasoner reasoner = GdlChainingReasoner.create(model); // GdlSentenceSet sentencesByForm = reasoner.getConstantSentences(); // addSentencesTrueByRulesDifferentially(sentencesByForm, model, reasoner); // return ImmutableConstantChecker.create(model, // Multimaps.filterKeys(sentencesByForm.getSentences(), Predicates.in(model.getConstantSentenceForms()))); //} //private static void addSentencesTrueByRulesDifferentially( // GdlSentenceSet sentencesByForm, // SentenceDomainModel domainModel, GdlChainingReasoner reasoner) { // SentenceFormModel model = domainModel; // Set<SentenceForm> constantForms = model.getConstantSentenceForms(); // //Find the part of the dependency graph dealing only with the constant forms. // MultiDictionary<SentenceForm, SentenceForm> dependencySubgraph = // Multimaps.filterKeys(model.getDependencyGraph(), Predicates.in(constantForms)); // dependencySubgraph = Multimaps.filterValues(model.getDependencyGraph(), Predicates.in(constantForms)); // dependencySubgraph = ImmutableMultimap.copyOf(dependencySubgraph); // List<Set<SentenceForm>> ordering = DependencyGraphs.toposortSafe(constantForms, dependencySubgraph); // foreach (Set<SentenceForm> stratum in ordering) { // // One non-differential pass, collecting the changes // GdlSentenceSet newlyTrueSentences = GdlSentenceSet.create(); // foreach (SentenceForm form in stratum) { // foreach (Implication rule in model.getRules(form)) { // GdlSentenceSet ruleResults = // reasoner.getRuleResults(rule, domainModel, sentencesByForm); // if (!reasoner.isSubsetOf(sentencesByForm, ruleResults)) { // sentencesByForm = reasoner.getUnion(sentencesByForm, ruleResults); // newlyTrueSentences = reasoner.getUnion(newlyTrueSentences, ruleResults); // } // } // } // // Now a lot of differential passes to deal with recursion efficiently // bool somethingChanged = true; // while (somethingChanged) { // somethingChanged = false; // GdlSentenceSet newStuffInThisPass = GdlSentenceSet.create(); // foreach (SentenceForm form in stratum) { // foreach (Implication rule in model.getRules(form)) { // GdlSentenceSet ruleResults = // reasoner.getRuleResultsForNewSentences(rule, domainModel, sentencesByForm, // newlyTrueSentences); // if (!reasoner.isSubsetOf(sentencesByForm, ruleResults)) { // somethingChanged = true; // newStuffInThisPass = reasoner.getUnion(newStuffInThisPass, ruleResults); // } // } // } // sentencesByForm = reasoner.getUnion(sentencesByForm, newStuffInThisPass); // newlyTrueSentences = newStuffInThisPass; // } // } //} /** * Precomputes the true sentences in every constant sentence form in the given * sentence model and returns the results in the form of a ConstantChecker. * * The implementation uses a backwards-chaining theorem prover. * * In most (but not all) cases, {@link #createWithForwardChaining(SentenceDomainModel)} * is more efficient. */ public static ImmutableConstantChecker CreateWithProver(ISentenceFormModel model) { var sentencesByForm = new MultiDictionary<ISentenceForm, Fact>(false); AddSentencesTrueByRules(sentencesByForm, model); return ImmutableConstantChecker.Create(model, sentencesByForm); }
//INFO: using the old BasicReasoner which appears to be much slower //private static void AddSentencesTrueByRules( // MultiDictionary<ISentenceForm, Fact> sentencesByForm, // ISentenceFormModel model) //{ // BasicReasoner prover = GameContainer.Reasoner; // var context = new ProofContext(new BasicKB(), GameContainer.Parser); // foreach (ISentenceForm form in model.ConstantSentenceForms) // { // Fact query = form.GetSentenceFromTuple(GetVariablesTuple(form.TupleSize)); // IEnumerable<GroundFact> answers = prover.GetAllAnswers(query, context); // foreach (GroundFact result in answers) // { // //ConcurrencyUtils.checkForInterruption(); // //Variables may end up being replaced with functions, which is not what we want here, so we have to double-check that the form is correct. // if (form.Matches(result)) // sentencesByForm.Add(form, result); // } // } //} private static void AddSentencesTrueByRules(MultiDictionary<ISentenceForm, Fact> sentencesByForm, ISentenceFormModel model) { AimaProver prover = new AimaProver(model.Description); foreach (ISentenceForm form in model.ConstantSentenceForms) { Fact query = form.GetSentenceFromTuple(GetVariablesTuple(form.TupleSize)); HashSet<Fact> context = new HashSet<Fact>(); foreach (Fact result in prover.AskAll(query, context)) if (form.Matches(result)) sentencesByForm.Add(form, result); } }
protected AbstractSentenceDomainModel(ISentenceFormModel formModel) { _formModel = formModel; }
private static MultiDictionary<int, ISentenceForm> GetFormsByName(ISentenceFormModel model) { var result = new MultiDictionary<int, ISentenceForm>(true); foreach (ISentenceForm value in GetAllSentenceForms(model)) result.Add(value.Name, value); return result; }
private static MultiDictionary<ISentenceForm, Ambiguity> GetAmbiguitiesByOriginalForm(ISentenceFormModel model) { var result = new MultiDictionary<ISentenceForm, Ambiguity>(true); MultiDictionary<int, ISentenceForm> formsByName = GetFormsByName(model); foreach (int name in formsByName.Keys) { ICollection<ISentenceForm> forms = formsByName[name]; foreach (ISentenceForm form in forms) result[form] = GetAmbiguities(form, forms); } ISet<ISentenceForm> allForms = formsByName.Values.ToImmutableHashSet(); foreach (Ambiguity ambiguity in result.Values) { Debug.Assert(allForms.Contains(ambiguity.Original)); Debug.Assert(allForms.Contains(ambiguity.Replacement)); } return result; }
private static IEnumerable<ISentenceForm> GetAllSentenceForms(ISentenceFormModel model) { // The model may only have sentence forms for sentences that can actually be true. It may be missing sentence forms that are used in // the rules only, with no actual corresponding sentences. We want to make sure these are included. var forms = new HashSet<ISentenceForm>(model.SentenceForms); GdlVisitors.VisitAll(model.Description, new GdlVisitor { VisitSentence = sentence => forms.Add(new SimpleSentenceForm(sentence)) }); return forms; }
private static IList<Expression> ApplyAmbiguitiesToRules(IEnumerable<Expression> description, MultiDictionary<ISentenceForm, Ambiguity> ambiguitiesByOriginalForm, ISentenceFormModel model) { ImmutableList<Expression>.Builder result = ImmutableList.CreateBuilder<Expression>(); foreach (Expression gdl in description) { var implication = gdl as Implication; if (implication != null) ApplyAmbiguities(implication, ambiguitiesByOriginalForm, model).ForEach(result.Add); else result.Add(gdl); } return result.ToImmutable(); }
internal UnusedSentenceNameSource(ISentenceFormModel model) { ISet<String> initialNames = SentenceForms.GetNames(model.SentenceForms); _allNamesSoFar = new HashSet<string>(initialNames); }