private static HashSet<Term> ToSampleTerms(TermModel termModel)
        {
            var results = new HashSet<Term>();
            if (termModel.PossibleConstants.Any())
                results.Add(termModel.PossibleConstants.First());

            foreach (NameAndArity nameAndArity in termModel.PossibleFunctions.Keys)
            {
                List<TermModel> bodyModel = termModel.PossibleFunctions[nameAndArity];
                IEnumerable<HashSet<Term>> functionSampleTerms = ToSampleTerms(bodyModel);
                var functionBodies = functionSampleTerms.CartesianProduct();
                foreach (IEnumerable<Term> functionBody in functionBodies)
                    results.Add(new TermFunction(nameAndArity.Name, functionBody.ToArray()));
            }
            return results;
        }
        public bool MergeIn(TermModel other)
        {
            bool changesMade = !PossibleConstants.IsSupersetOf(other.PossibleConstants);
            PossibleConstants.UnionWith(other.PossibleConstants);
            foreach (NameAndArity key in other.PossibleFunctions.Keys)
            {
                List<TermModel> theirFunctionBodies = other.PossibleFunctions[key];
                if (PossibleFunctions.ContainsKey(key))
                {
                    List<TermModel> ourFunctionBodies = PossibleFunctions[key];
                    if (ourFunctionBodies.Count != theirFunctionBodies.Count)
                        throw new Exception();

                    for (int i = 0; i < ourFunctionBodies.Count; i++)
                        changesMade |= ourFunctionBodies[i].MergeIn(theirFunctionBodies[i]);
                }
                else
                {
                    PossibleFunctions[key] = DeepCopyOf(theirFunctionBodies);
                    changesMade = true;
                }
            }
            return changesMade;
        }
 private static TermModel CopyOf(TermModel originalTermModel)
 {
     var termModel = new TermModel();
     termModel.MergeIn(originalTermModel);
     return termModel;
 }
        private Dictionary<TermVariable, TermModel> GetVarsToModelsMap(Implication rule)
        {
            var varsToUse = new HashSet<TermVariable>(rule.Consequent.VariablesOrEmpty);
            var varsToModelsMap = new Dictionary<TermVariable, TermModel>();
            foreach (TermVariable var in varsToUse)
                varsToModelsMap[var] = new TermModel();

            foreach (Expression literal in rule.Antecedents.Conjuncts)
            {
                var fact = literal as Fact;
                if (fact != null)
                {
                    List<Term> literalBody = fact.GetTerms();
                    var nameAndArity = new NameAndArity(fact);
                    SentencesModel.CreateIfRequired(nameAndArity);
                    List<TermModel> literalModel = SentencesModel[nameAndArity];
                    AddVariablesToMap(literalBody, literalModel, varsToModelsMap);
                }
            }
            return varsToModelsMap;
        }