コード例 #1
0
        public CartesianSentenceFormDomain(ISentenceForm form, IDictionary<int, ICollection<TermObject>> setMultimap)
        {
            Debug.Assert(setMultimap != null);

            var domainsForSlots = new List<ISet<TermObject>>();
            for (int i = 0; i < form.TupleSize; i++)
            {
                ICollection<TermObject> possibleDomain;
                if (!setMultimap.TryGetValue(i, out possibleDomain))
                    possibleDomain = new List<TermObject>();
                domainsForSlots.Add(new HashSet<TermObject>(possibleDomain));
            }
            _form = form;
            _domainsForSlots = domainsForSlots.Select(s => new JavaHashSet<TermObject>(s)).ToImmutableList();
        }
コード例 #2
0
ファイル: FunctionInfoImpl.cs プロジェクト: druzil/nggp-base
        public FunctionInfoImpl(ISentenceForm form, ISet<Fact> trueSentences)
        {
            _form = form;

            int numSlots = form.TupleSize;

            for (int i = 0; i < numSlots; i++)
            {
                //We want to establish whether or not this is a constant...
                IDictionary<AssignmentFunctionQueryTuple, TermObject> functionMap = new Dictionary<AssignmentFunctionQueryTuple, TermObject>();
                bool functional = true;
                foreach (Fact sentence in trueSentences)
                {
                    //ConcurrencyUtils.checkForInterruption();
                    List<TermObject> tuple = sentence.TermObjects.ToList();
                    var tuplePart = new AssignmentFunctionQueryTuple(tuple.Count - 1);
                    tuplePart.AddRange(tuple.GetRange(0, i));
                    tuplePart.AddRange(tuple.GetRange(i + 1, tuple.Count - i - 1));
                    if (functionMap.ContainsKey(tuplePart))
                    {
                        //We have two tuples with different values in just this slot
                        functional = false;
                        break;
                    }
                    //Otherwise, we record it
                    functionMap[new AssignmentFunctionQueryTuple(tuplePart)] = tuple[i];
                }

                if (functional)
                {
                    //Record the function
                    _dependentSlots.Add(true);
                    _valueMaps.Add(functionMap);
                }
                else
                {
                    //Forget it
                    _dependentSlots.Add(false);
                    _valueMaps.Add(null);
                }
            }
        }
コード例 #3
0
        public static AssignmentsImpl GetAssignmentsWithRecursiveInput(Implication rule,
                                                                       ISentenceDomainModel model, ISentenceForm form, Fact input,
                                                                       Dictionary<ISentenceForm, FunctionInfo> functionInfoMap,
                                                                       Dictionary<ISentenceForm, ICollection<Fact>> completedSentenceFormValues)
        {
            //Look for the literal(s) in the rule with the sentence form of the
            //recursive input. This can be tricky if there are multiple matching
            //literals.
            var matchingLiterals = rule.Antecedents.Conjuncts.OfType<Fact>().Where(form.Matches).ToList();

            var assignmentsList = new List<AssignmentsImpl>();
            foreach (Fact matchingLiteral in matchingLiterals)
            {
                var preassignment = new TermObjectSubstitution();
                preassignment.Add(matchingLiteral.Unify(input));
                if (preassignment.NumMappings() > 0)
                {
                    var assignments = new AssignmentsImpl(
                        preassignment,
                        rule,
                        //TODO: This one getVarDomains call is why a lot of
                        //SentenceModel/DomainModel stuff is required. Can
                        //this be better factored somehow?
                        SentenceDomainModels.GetVarDomains(rule, model, SentenceDomainModels.VarDomainOpts.IncludeHead),
                        functionInfoMap,
                        completedSentenceFormValues);
                    assignmentsList.Add(assignments);
                }
            }

            if (assignmentsList.Count == 0)
                return new AssignmentsImpl();
            if (assignmentsList.Count == 1)
                return assignmentsList[0];
            throw new Exception("Not yet implemented: assignments for recursive functions with multiple recursive conjuncts");
            //TODO: Plan to implement by subclassing TermObjectSubstitution into something
            //that contains and iterates over multiple TermObjectSubstitution
        }
コード例 #4
0
 public ISet<Implication> GetRules(ISentenceForm form)
 {
     return new HashSet<Implication>(_rulesByForm[form]);
 }
コード例 #5
0
ファイル: FunctionInfoImpl.cs プロジェクト: druzil/nggp-base
 public static FunctionInfo Create(ISentenceForm form, ISet<Fact> set)
 {
     return new FunctionInfoImpl(form, set);
 }
コード例 #6
0
ファイル: FunctionInfoImpl.cs プロジェクト: druzil/nggp-base
 public static FunctionInfo Create(ISentenceForm form, IConstantChecker constantChecker)
 {
     return new FunctionInfoImpl(form, constantChecker.GetTrueSentences(form));
 }
コード例 #7
0
 public CondensorSentenceDomainModel(ISentenceForm newForm, ISentenceFormDomain newFormDomain, ISentenceDomain oldModel)
 {
     _newForm = newForm;
     _newFormDomain = newFormDomain;
     _oldModel = oldModel;
 }
コード例 #8
0
ファイル: SentenceFormAdder.cs プロジェクト: druzil/nggp-base
        public void AddSentenceForm(ISentenceForm form, ISentenceDomainModel model,
            IDictionary<Fact, IComponent> components,
            IDictionary<Fact, IComponent> negations, IConstant trueComponent, IConstant falseComponent,
            bool usingBase, bool usingInput, ISet<ISentenceForm> recursionForms,
            IDictionary<Fact, IComponent> temporaryComponents, IDictionary<Fact, IComponent> temporaryNegations,
            Dictionary<ISentenceForm, FunctionInfo> functionInfoMap, IConstantChecker constantChecker,
            Dictionary<ISentenceForm, ICollection<Fact>> completedSentenceFormValues)
        {
            //This is the meat of it (along with the entire Assignments class).
            //We need to enumerate the possible propositions in the sentence form...
            //We also need to hook up the sentence form to the inputs that can make it true.
            //We also try to optimize as we go, which means possibly removing the
            //proposition if it isn't actually possible, or replacing it with
            //true/false if it's a constant.

            ISet<Fact> alwaysTrueSentences = model.GetSentencesListedAsTrue(form);
            ISet<Implication> rules = model.GetRules(form);

            foreach (Fact alwaysTrueSentence in alwaysTrueSentences)
            {
                //We add the sentence as a constant
                if (alwaysTrueSentence.RelationName == GameContainer.Parser.TokLegal
                    || alwaysTrueSentence.RelationName == GameContainer.Parser.TokNext
                    || alwaysTrueSentence.RelationName == GameContainer.Parser.TokGoal)
                {
                    var prop = _componentFactory.CreateProposition(alwaysTrueSentence);
                    //Attach to true
                    trueComponent.AddOutput(prop);
                    prop.AddInput(trueComponent);
                    //Still want the same components;
                    //we just don't want this to be anonymized
                }
                //Assign as true
                components[alwaysTrueSentence] = trueComponent;
                negations[alwaysTrueSentence] = falseComponent;
            }

            //For does/true, make nodes based on input/base, if available
            if (usingInput && form.Name.Equals(GameContainer.Parser.TokDoes))
            {
                //Add only those propositions for which there is a corresponding INPUT
                ISentenceForm inputForm = form.WithName(GameContainer.SymbolTable["input"]);
                foreach (Fact inputSentence in constantChecker.GetTrueSentences(inputForm))
                {
                    Fact doesSentence = _doesProcessor.ProcessBaseFact(inputSentence);
                    var prop = _componentFactory.CreateProposition(doesSentence);
                    components[doesSentence] = prop;
                }
                return;
            }
            if (usingBase && form.Name.Equals(GameContainer.Parser.TokTrue))
            {
                ISentenceForm baseForm = form.WithName(GameContainer.SymbolTable["base"]);
                foreach (Fact baseSentence in constantChecker.GetTrueSentences(baseForm))
                {
                    Fact trueSentence = _trueProcessor.ProcessBaseFact(baseSentence);
                    IProposition prop = _componentFactory.CreateProposition(trueSentence);
                    components[trueSentence] = prop;
                }
                return;
            }

            //var recursiveFormCache = new RecursionFormsCache(recursionForms);

            var inputsToOr = new Dictionary<Fact, HashSet<IComponent>>();
            foreach (Implication rule in rules)
            {
                AssignmentsImpl assignments = AssignmentsFactory.GetAssignmentsForRule(rule, model, functionInfoMap,
                    completedSentenceFormValues);

                //Calculate vars in live (non-constant, non-distinct) conjuncts
                ISet<TermVariable> varsInLiveConjuncts = GetVarsInLiveConjuncts(rule,
                    constantChecker.ConstantSentenceForms);
                foreach (var head in rule.Consequent.VariablesOrEmpty)
                    varsInLiveConjuncts.Add(head);
                var varsInRule = new HashSet<TermVariable>(rule.VariablesOrEmpty);
                bool preventDuplicatesFromConstants = varsInRule.Count > varsInLiveConjuncts.Count;

                bool[] constantFormCheck = new bool[rule.Antecedents.Constituents.Length];
                for (int i = 0; i < rule.Antecedents.Constituents.Length; i++)
                {
                    Expression literal = rule.Antecedents.Constituents[i];
                    var fact = literal as Fact;
                    var negated = literal as Negation;
                    if (fact != null || negated != null)
                    {
                        if (negated != null)
                            fact = (Fact) negated.Negated;

                        ISentenceForm conjunctForm = model.GetSentenceForm(fact);
                        if (constantChecker.IsConstantForm(conjunctForm))
                            constantFormCheck[i] = true;
                    }
                }

                for (var asnItr = (AssignmentIteratorImpl) assignments.GetEnumerator(); asnItr.MoveNext();)
                {
                    TermObjectSubstitution assignment = asnItr.Current;
                    if (assignment == null)
                        continue; //Not sure if this will ever happen

                    //ConcurrencyUtils.checkForInterruption();

                    var sentence = (Fact) rule.Consequent.ApplySubstitution(assignment);

                    //Now we go through the conjuncts as before, but we wait to hook them up.
                    var componentsToConnect = new List<IComponent>(rule.Consequent.Arity);
                    for (int i = 0; i < rule.Antecedents.Constituents.Length; i++)
                    {
                        Expression literal = rule.Antecedents.Constituents[i];
                        var fact = literal as Fact;
                        if (fact != null)
                        {
                            if (fact.RelationName != GameContainer.Parser.TokDistinct)
                            {
                                //Get the sentence post-substitutions
                                var transformed = (Fact) literal.ApplySubstitution(assignment);

                                //Check for constant-ness
                                //ISentenceForm conjunctForm = model.GetSentenceForm(transformed);
                                //if (constantChecker.IsConstantForm(conjunctForm))
                                if (constantFormCheck[i])
                                {
                                    if (!constantChecker.IsTrueConstant(transformed))
                                    {
                                        List<TermVariable> varsToChange = GetVarsInConjunct(literal);
                                        asnItr.ChangeOneInNext(varsToChange, assignment);
                                        componentsToConnect.Add(null);
                                    }
                                    continue;
                                }

                                //If conj is null and this is a sentence form we're still handling, hook up to a temporary sentence form
                                IComponent conj;
                                if (!components.TryGetValue(transformed, out conj))
                                    temporaryComponents.TryGetValue(transformed, out conj);

                                if (conj == null && InSentenceFormGroup(transformed, recursionForms))
                                {
                                    //Set up a temporary component
                                    var tempProp = _componentFactory.CreateProposition(transformed);
                                    temporaryComponents[transformed] = tempProp;
                                    conj = tempProp;
                                }
                                //Let's say this is false; we want to backtrack and change the right variable
                                if (conj == null || IsThisConstant(conj, falseComponent))
                                {
                                    List<TermVariable> varsInConjunct = GetVarsInConjunct(literal);
                                    asnItr.ChangeOneInNext(varsInConjunct, assignment);
                                    //These last steps just speed up the process
                                    //telling the factory to ignore this rule
                                    componentsToConnect.Add(null);
                                    continue; //look at all the other restrictions we'll face
                                }

                                componentsToConnect.Add(conj);
                            }
                        }
                        else
                        {
                            var negation = literal as Negation;
                            if (negation != null)
                            {
                                //Add a "not" if necessary
                                //Look up the negation
                                var inner = (Fact) negation.Negated;
                                var transformed = (Fact) inner.ApplySubstitution(assignment);

                                //Add constant-checking here...
                                //ISentenceForm conjunctForm = model.GetSentenceForm(transformed);
                                //if (constantChecker.IsConstantForm(conjunctForm))
                                if (constantFormCheck[i])
                                {
                                    if (constantChecker.IsTrueConstant(transformed))
                                    {
                                        List<TermVariable> varsToChange = GetVarsInConjunct(negation);
                                        asnItr.ChangeOneInNext(varsToChange, assignment);
                                        componentsToConnect.Add(null);
                                    }
                                    continue;
                                }

                                IComponent conj;
                                negations.TryGetValue(transformed, out conj);
                                if (IsThisConstant(conj, falseComponent))
                                {
                                    //We need to change one of the variables inside
                                    List<TermVariable> varsInConjunct = GetVarsInConjunct(inner);
                                    asnItr.ChangeOneInNext(varsInConjunct, assignment);
                                    //ignore this rule
                                    componentsToConnect.Add(null);
                                    continue;
                                }
                                if (conj == null)
                                    temporaryNegations.TryGetValue(transformed, out conj);

                                //Check for the recursive case:
                                if (conj == null && InSentenceFormGroup(transformed, recursionForms))
                                {
                                    IComponent positive;
                                    if (!components.TryGetValue(transformed, out positive))
                                        temporaryComponents.TryGetValue(transformed, out positive);

                                    if (positive == null)
                                    {
                                        //Make the temporary proposition
                                        var tempProp = _componentFactory.CreateProposition(transformed);
                                        temporaryComponents[transformed] = tempProp;
                                        positive = tempProp;
                                    }
                                    //Positive is now set and in temporaryComponents
                                    //Evidently, wasn't in temporaryNegations
                                    //So we add the "not" gate and set it in temporaryNegations
                                    var not = _componentFactory.CreateNot();
                                    //Add positive as input
                                    not.AddInput(positive);
                                    positive.AddOutput(not);
                                    temporaryNegations[transformed] = not;
                                    conj = not;
                                }
                                if (conj == null)
                                {
                                    IComponent positive;
                                    components.TryGetValue(transformed, out positive);
                                    //No, because then that will be attached to "negations", which could be bad

                                    if (positive == null)
                                    {
                                        //So the positive can't possibly be true (unless we have recurstion)
                                        //and so this would be positive always
                                        //We want to just skip this conjunct, so we continue to the next

                                        continue; //to the next conjunct
                                    }

                                    //Check if we're sharing a component with another sentence with a negation
                                    //(i.e. look for "nots" in our outputs and use those instead)
                                    INot existingNotOutput = GetNotOutput(positive);
                                    if (existingNotOutput != null)
                                    {
                                        componentsToConnect.Add(existingNotOutput);
                                        negations[transformed] = existingNotOutput;
                                        continue; //to the next conjunct
                                    }

                                    var not = _componentFactory.CreateNot();
                                    not.AddInput(positive);
                                    positive.AddOutput(not);
                                    negations[transformed] = not;
                                    conj = not;
                                }
                                componentsToConnect.Add(conj);
                            }
                            else
                            {
                                throw new Exception("Unwanted Expression type");
                            }
                        }
                    }
                    if (!componentsToConnect.Contains(null))
                    {
                        //Connect all the components
                        IProposition andComponent = _componentFactory.CreateProposition(_tempFact);

                        Andify(componentsToConnect, andComponent, trueComponent);
                        if (!IsThisConstant(andComponent, falseComponent))
                        {
                            if (!inputsToOr.ContainsKey(sentence))
                                inputsToOr[sentence] = new HashSet<IComponent>();
                            inputsToOr[sentence].Add(andComponent);
                            //We'll want to make sure at least one of the non-constant
                            //components is changing
                            if (preventDuplicatesFromConstants)
                                asnItr.ChangeOneInNext(varsInLiveConjuncts, assignment);
                        }
                    }
                }
            }

            //At the end, we hook up the conjuncts
            foreach (var entry in inputsToOr)
            {
                //ConcurrencyUtils.checkForInterruption();

                Fact sentence = entry.Key;
                HashSet<IComponent> inputs = entry.Value;
                var realInputs = new HashSet<IComponent>();
                foreach (IComponent input in inputs)
                    if (input is IConstant || !input.Inputs.Any())
                        realInputs.Add(input);
                    else
                    {
                        realInputs.Add(input.GetSingleInput());
                        input.GetSingleInput().RemoveOutput(input);
                        input.RemoveAllInputs();
                    }

                var prop = _componentFactory.CreateProposition(sentence);
                Orify(realInputs, prop, falseComponent);
                components[sentence] = prop;
            }

            //True/does sentences will have none of these rules, but
            //still need to exist/"float"
            //We'll do this if we haven't used base/input as a basis
            if (form.Name.Equals(GameContainer.Parser.TokTrue) || form.Name.Equals(GameContainer.Parser.TokDoes))
                foreach (Fact sentence in model.GetDomain(form)) //ConcurrencyUtils.checkForInterruption();
                    components[sentence] = _componentFactory.CreateProposition(sentence);
        }
コード例 #9
0
 public override ISentenceFormDomain GetDomain(ISentenceForm form)
 {
     ISentenceFormDomain result;
     _domains.TryGetValue(form, out result);
     return result;
 }
コード例 #10
0
 public ISet<Implication> GetRules(ISentenceForm form)
 {
     return _formModel.GetRules(form);
 }
コード例 #11
0
ファイル: Relationizer.cs プロジェクト: druzil/nggp-base
        private static Expression ReplaceRelationInLiteral(Expression literal, ISentenceForm trueForm)
        {
            var sentence = literal as Fact;
            if (sentence != null)
                if (trueForm.Matches(sentence))
                {
                    var terms = sentence.GetTerms();
                    var function = terms[0] as TermFunction;
                    Debug.Assert(function != null);
                    return new VariableFact(true, function.FunctionName, function.Arguments);
                }
                else
                    return literal;

            var not = literal as Negation;
            if (not != null)
                return new Negation(ReplaceRelationInLiteral(not.Negated, trueForm));

            var or = literal as Disjunction;
            if (or != null)
            {
                var newOrBody = new List<Expression>();
                for (int i = 0; i < or.GetDisjuncts().Count(); i++)
                    newOrBody.Add(ReplaceRelationInLiteral(or.Constituents[i], trueForm));
                return new Disjunction(newOrBody.ToArray());
            }
            throw new Exception(string.Format("Unanticipated GDL literal type {0} encountered in Relationizer", literal.GetType()));
        }
コード例 #12
0
ファイル: Relationizer.cs プロジェクト: druzil/nggp-base
 private static List<Expression> ReplaceRelationInBody(IEnumerable<Expression> body, ISentenceForm trueForm)
 {
     return body.Select(literal => ReplaceRelationInLiteral(literal, trueForm)).ToList();
 }
コード例 #13
0
 public Ambiguity(ISentenceForm original, Dictionary<int, TermFunction> replacementsByOriginalTupleIndex,
     ISentenceForm replacement)
 {
     Debug.Assert(original != null);
     Debug.Assert(replacementsByOriginalTupleIndex != null);
     Debug.Assert(replacementsByOriginalTupleIndex.Any());
     Debug.Assert(replacement != null);
     foreach (int varIndex in replacementsByOriginalTupleIndex.Keys)
         Debug.Assert(varIndex < original.TupleSize);
     Original = original;
     _replacementsByOriginalTupleIndex = replacementsByOriginalTupleIndex.ToImmutableDictionary();
     Replacement = replacement;
 }
コード例 #14
0
 private static List<Ambiguity> GetAmbiguities(ISentenceForm original, IEnumerable<ISentenceForm> forms)
 {
     return forms.Select(form => FindAmbiguity(original, form)).Where(ambiguity => ambiguity != null).ToList();
 }
コード例 #15
0
        private static Ambiguity FindAmbiguity(ISentenceForm original, ISentenceForm replacement)
        {
            Debug.Assert(original.Name == replacement.Name);
            if (original.Equals(replacement))
                return null;

            var replacementsByOriginalTupleIndex = new Dictionary<int, TermFunction>();
            //Make the arguments ?v0, ?v1, ?v2, ... so we can find the tuple indices easily
            Fact originalSentence = original.GetSentenceFromTuple(GetNumberedTuple(original.TupleSize));
            Fact replacementSentence = replacement.GetSentenceFromTuple(GetNumberedTuple(replacement.TupleSize));

            bool success = FindAmbiguity(originalSentence.GetTerms(), replacementSentence.GetTerms(), replacementsByOriginalTupleIndex);
            return success ? new Ambiguity(original, replacementsByOriginalTupleIndex, replacement) : null;
        }
コード例 #16
0
 public ISet<Fact> GetSentencesListedAsTrue(ISentenceForm form)
 {
     return new HashSet<Fact>(_trueSentencesByForm[form]);
 }
コード例 #17
0
 public CartesianSentenceFormDomain(ISentenceForm form, IEnumerable<ISet<TermObject>> domainsForSlots)
 {
     _form = form;
     _domainsForSlots = domainsForSlots.Select(s => new JavaHashSet<TermObject>(s)).ToImmutableList();
 }
コード例 #18
0
 public abstract ISentenceFormDomain GetDomain(ISentenceForm form);
コード例 #19
0
 private static void AddFormToCompletedValues(ISentenceForm form, Dictionary<ISentenceForm, ICollection<Fact>> completedSentenceFormValues,
     IConstantChecker constantChecker)
 {
     completedSentenceFormValues[form] = new List<Fact>(constantChecker.GetTrueSentences(form));
 }
コード例 #20
0
 public ISet<Fact> GetSentencesListedAsTrue(ISentenceForm form)
 {
     return _formModel.GetSentencesListedAsTrue(form);
 }
コード例 #21
0
 public ISet<Fact> GetTrueSentences(ISentenceForm form)
 {
     return new HashSet<Fact>(_sentencesByForm[form]);
 }
コード例 #22
0
 private static void AddConstantsToFunctionInfo(ISentenceForm form, IConstantChecker constantChecker,
                                                IDictionary<ISentenceForm, FunctionInfo> functionInfoMap)
 {
     functionInfoMap[form] = FunctionInfoImpl.Create(form, constantChecker);
 }
コード例 #23
0
 public ISentenceFormDomain GetDomain(ISentenceForm form)
 {
     return form.Equals(_newForm) ? _newFormDomain : _oldModel.GetDomain(form);
 }
コード例 #24
0
 private static void AddFormToCompletedValues(ISentenceForm form, IDictionary<ISentenceForm, ICollection<Fact>> completedSentenceFormValues,
     Dictionary<Fact, IComponent> components)
 {
     //Kind of inefficient. Could do better by collecting these as we go,
     //then adding them back into the CSFV map once the sentence forms are complete.
     //completedSentenceFormValues.put(form, new ArrayList<Fact>());
     completedSentenceFormValues[form] = components.Keys.Where(form.Matches).ToList();
 }
コード例 #25
0
 private CartesianSentenceFormDomain GetDomain(ISentenceForm form, Fact sentence)
 {
     var domainContents = new List<ISet<TermObject>>();
     GetDomainInternal(sentence.GetTerms(), _sentencesModel.GetBodyModel(sentence), domainContents);
     return new CartesianSentenceFormDomain(form, domainContents);
 }
コード例 #26
0
 public bool IsConstantForm(ISentenceForm form)
 {
     return _sentenceModel.ConstantSentenceForms.Contains(form);
 }
コード例 #27
0
        private static ISentenceFormDomain GetNewFormDomain(Implication condensingRule, ISentenceDomain oldModel, ISentenceForm newForm)
        {
            var varDomains = SentenceDomainModels.GetVarDomains(condensingRule, oldModel, SentenceDomainModels.VarDomainOpts.BodyOnly);

            var domainsForSlots = new List<ISet<TermObject>>();
            foreach (Term term in condensingRule.Consequent.NestedTerms)
            {
                if (!(term is TermVariable))
                    throw new Exception("Expected all slots in the head of a condensing rule to be variables, but the rule was: " + condensingRule);
                domainsForSlots.Add(varDomains[(TermVariable)term]);
            }
            return new CartesianSentenceFormDomain(newForm, domainsForSlots);
        }