Esempio n. 1
0
 public CondensorSentenceDomainModel(ISentenceForm newForm, ISentenceFormDomain newFormDomain, ISentenceDomain oldModel)
 {
     _newForm = newForm;
     _newFormDomain = newFormDomain;
     _oldModel = oldModel;
 }
Esempio n. 2
0
        private static bool GoodCondensationSetByHeuristic(ICollection<Expression> minSet, Implication rule, ISentenceDomain model,
            IConstantChecker checker, UnusedSentenceNameSource sentenceNameSource)
        {
            //We actually want the sentence model here so we can see the domains
            //also, if it's a constant, ...
            //Anyway... we want to compare the heuristic for the number of assignments
            //and/or links that will be generated with or without the condensation set
            //Heuristic for a rule is A*(L+1), where A is the number of assignments and
            //L is the number of literals, unless L = 1, in which case the heuristic is
            //just A. This roughly captures the number of links that would be generated
            //if this rule were to be generated.
            //Obviously, there are differing degrees of accuracy with which we can
            //represent A.
            //One way is taking the product of all the variables in all the domains.
            //However, we can do better by actually asking the Assignments class for
            //its own heuristic of how it would implement the rule as-is.
            //The only tricky aspect here is that we need an up-to-date SentenceModel,
            //and in some cases this could be expensive to compute. Might as well try
            //it, though...

            //Heuristic for the rule as-is:

            long assignments = AssignmentsImpl.GetNumAssignmentsEstimate(rule,
                SentenceDomainModels.GetVarDomains(rule, model, SentenceDomainModels.VarDomainOpts.IncludeHead),
                checker);
            int literals = rule.Consequent.Arity;
            if (literals > 1)
                literals++;

            //We have to "and" the literals together
            //Note that even though constants will be factored out, we're concerned here
            //with getting through them in a reasonable amount of time, so we do want to
            //count them. TODO: Not sure if they should be counted in L, though...
            long curRuleHeuristic = assignments * literals;
            //And if we split them up...
            List<Implication> newRules = ApplyCondensation(minSet, rule, sentenceNameSource);
            Implication r1 = newRules[0], r2 = newRules[1];

            //Augment the model
            ISentenceDomain newModel = AugmentModelWithNewForm(model, newRules);

            long a1 = AssignmentsImpl.GetNumAssignmentsEstimate(r1,
                SentenceDomainModels.GetVarDomains(r1, newModel, SentenceDomainModels.VarDomainOpts.IncludeHead), checker);
            long a2 = AssignmentsImpl.GetNumAssignmentsEstimate(r2,
                SentenceDomainModels.GetVarDomains(r2, newModel, SentenceDomainModels.VarDomainOpts.IncludeHead), checker);
            int l1 = r1.Consequent.Arity; if (l1 > 1) l1++;
            int l2 = r2.Consequent.Arity; if (l2 > 1) l2++;

            //Whether we split or not depends on what the two heuristics say
            long newRulesHeuristic = a1 * l1 + a2 * l2;
            return newRulesHeuristic < curRuleHeuristic;
        }
Esempio n. 3
0
        private static ISet<Expression> GetCondensationSet(Implication rule, ISentenceDomain model, IConstantChecker checker,
                                                           UnusedSentenceNameSource sentenceNameSource)
        {
            //We use each variable as a starting point
            List<TermVariable> varsInRule = rule.VariablesOrEmpty.ToList();
            List<TermVariable> varsInHead = rule.Consequent.VariablesOrEmpty.ToList();
            var varsNotInHead = new List<TermVariable>(varsInRule);
            varsNotInHead.RemoveAll(varsInHead.Contains);

            foreach (TermVariable var in varsNotInHead)
            {
                var minSet = new HashSet<Expression>();
                foreach (Expression literal in rule.Antecedents.Conjuncts)
                    if (literal.VariablesOrEmpty.Contains(var))
                        minSet.Add(literal);

                //#1 is already done
                //Now we try #2
                var varsNeeded = new HashSet<TermVariable>();
                var varsSupplied = new HashSet<TermVariable>();
                foreach (Expression literal in minSet)
                {
                    if (literal is Negation)
                    {
                        foreach (var variable in literal.VariablesOrEmpty)
                            varsNeeded.Add(variable);
                    }
                    else if (literal is Fact)
                    {
                        if (((Fact)literal).RelationName == GameContainer.Parser.TokDistinct)
                            foreach (var variable in literal.VariablesOrEmpty)
                                varsNeeded.Add(variable);
                        else
                            foreach (var variable in literal.VariablesOrEmpty)
                                varsSupplied.Add(variable);
                    }
                }
                varsNeeded.RemoveWhere(varsSupplied.Contains);
                if (varsNeeded.Any())
                    continue;

                var candidateSuppliersList = new List<ISet<Expression>>();
                foreach (TermVariable varNeeded in varsNeeded)
                {
                    var suppliers = new HashSet<Expression>();
                    foreach (Expression literal in rule.Antecedents.Conjuncts)
                        if (literal is Fact)
                            if (literal.VariablesOrEmpty.Contains(varNeeded))
                                suppliers.Add(literal);
                    candidateSuppliersList.Add(suppliers);
                }

                //TODO: Now... I'm not sure if we want to minimize the number of literals added, or the number of variables added
                //Right now, I don't have time to worry about optimization. Currently, we pick one at random
                //TODO: Optimize this
                var literalsToAdd = new HashSet<Expression>();
                foreach (ISet<Expression> suppliers in candidateSuppliersList)
                    if (!suppliers.Intersect(literalsToAdd).Any())
                        literalsToAdd.Add(suppliers.First());

                minSet.UnionWith(literalsToAdd);

                if (GoodCondensationSetByHeuristic(minSet, rule, model, checker, sentenceNameSource))
                    return minSet;

            }
            return null;
        }
Esempio n. 4
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);
        }
Esempio n. 5
0
 private static ISentenceDomain AugmentModelWithNewForm(ISentenceDomain oldModel, List<Implication> newRules)
 {
     var newForm = new SimpleSentenceForm(newRules[0].Consequent);
     ISentenceFormDomain newFormDomain = GetNewFormDomain(newRules[0], oldModel, newForm);
     return new CondensorSentenceDomainModel(newForm, newFormDomain, oldModel);
 }