public void ApplySubMap(SubstitutionMap subMap)
 {
     foreach (var atom in Atoms)
     {
         atom.ApplySubMap(subMap);
     }
 }
 public Term(Term term)
 {
     Id      = term.Id;
     ParentA = term.ParentA;
     ParentB = term.ParentB;
     Atoms   = new List <Atom>();
     foreach (var atom in term.Atoms)
     {
         Atoms.Add(new Atom(atom));
     }
     SubMap   = new SubstitutionMap(term.SubMap);
     FromGoal = term.FromGoal;
 }
        private static SubstitutionMap Unify(Atom a, Atom b, SubstitutionMap subMap)
        {
            var output = new SubstitutionMap(subMap);

            if (a.Name != b.Name || a.Arguments.Count != b.Arguments.Count)
            {
                output.Failure = true;
                return(output);
            }

            var atomA = new Atom(a);
            var atomB = new Atom(b);

            atomA.ApplySubMap(output);
            atomB.ApplySubMap(output);

            var disagreement = false;

            for (var i = 0; i < atomA.Arguments.Count; i++)
            {
                var argA = atomA.Arguments[i];
                var argB = atomB.Arguments[i];
                if (argA.EqualTo(argB))
                {
                    continue;
                }

                disagreement = true;
                if (argA.CanMapTo(argB))
                {
                    subMap.Add(argA, argB);
                    var newOutput = Unify(atomA, atomB, subMap);
                    newOutput.Changed = true;
                    return(newOutput);
                }
                if (argB.CanMapTo(argA))
                {
                    subMap.Add(argB, argA);
                    var newOutput = Unify(atomA, atomB, subMap);
                    newOutput.Changed = true;
                    return(newOutput);
                }
                break;
            }
            if (disagreement)
            {
                output.Failure = true;
            }
            return(output);
        }
 public SubstitutionMap(SubstitutionMap subMap)
 {
     if (subMap._vars.Count > 0)
     {
         _vars = new Dictionary <Argument, Argument>();
         foreach (var key in subMap.Keys)
         {
             _vars.Add(new Argument(key), new Argument(subMap.Get(key)));
         }
     }
     else
     {
         _vars = new Dictionary <Argument, Argument>();
     }
 }
 public bool EqualTo(SubstitutionMap subMap)
 {
     if (Keys.Count() != subMap.Keys.Count())
     {
         return(false);
     }
     foreach (var mySubs in _vars)
     {
         if (!subMap.ContainsKey(mySubs.Key))
         {
             return(false);
         }
         if (!subMap.Get(mySubs.Key).EqualTo(Get(mySubs.Key)))
         {
             return(false);
         }
     }
     return(true);
 }
        private static SubstitutionMap UnifySubMap(SubstitutionMap subMapA, SubstitutionMap subMapB)
        {
            var output = new SubstitutionMap();

            foreach (var keyA in subMapA.Keys)
            {
                if (subMapB.ContainsKey(keyA))
                {
                    output.Failure = true;
                    return(output);
                }
                output.Add(keyA, subMapA.Get(keyA));
            }
            foreach (var keyB in subMapB.Keys)
            {
                output.Add(keyB, subMapB.Get(keyB));
            }

            return(output);
        }
        public void InnerLoop(List <Argument> arguments, SubstitutionMap subMap)
        {
            foreach (var arg in arguments)
            {
                switch (arg.Type)
                {
                case ArgType.Constant:
                    continue;

                case ArgType.Variable:
                    if (subMap.ContainsKey(arg))
                    {
                        var otherArg = subMap.Get(arg);
                        arg.Name = otherArg.Name;
                        arg.Type = otherArg.Type;
                        if (otherArg.Arguments != null && otherArg.Arguments.Count > 0)
                        {
                            arg.Arguments = new List <Argument>(otherArg.Arguments);
                        }
                    }
                    continue;

                case ArgType.Function:
                    if (subMap.ContainsKey(arg))
                    {
                        var otherArg = new Argument(subMap.Get(arg));
                        arg.Name      = otherArg.Name;
                        arg.Type      = otherArg.Type;
                        arg.Arguments = new List <Argument>(otherArg.Arguments);
                    }
                    else
                    {
                        InnerLoop(arg.Arguments, subMap);
                    }
                    continue;
                }
            }
        }
        private static List <Atom> GetCombinedAtoms(Term a, Term b, SubstitutionMap subMap)
        {
            //apply combined submap to each term
            var termA = new Term(a);
            var termB = new Term(b);

            termA.ApplySubMap(subMap);
            termB.ApplySubMap(subMap);
            var output = new List <Atom>();

            //add all of term A's atoms if they check out
            var allFailed = true;

            foreach (var atomA in termA.Atoms)
            {
                var atomToAdd = atomA;
                foreach (var atomB in termB.Atoms)
                {
                    var unifyResult = Unify(atomA, atomB, subMap);
                    if (unifyResult.Failure)
                    {
                        continue;
                    }
                    allFailed = false;
                    if (unifyResult.Changed)
                    {
                        return(GetCombinedAtoms(termA, termB, unifyResult));
                    }
                    atomToAdd = new Atom
                    {
                        Name         = "",
                        Arguments    = null,
                        IsBool       = true,
                        Truthfulness = (atomA.Truthfulness == atomB.Truthfulness)
                    };
                    break;
                }
                output.Add(atomToAdd);
                if (atomToAdd.IsBool && atomToAdd.Truthfulness)
                {
                    return(output);
                }
            }
            //add all of term B's atoms if they check out
            foreach (var atomB in termB.Atoms)
            {
                var atomToAdd = atomB;
                foreach (var atomA in termA.Atoms)
                {
                    var unifyResult = Unify(atomB, atomA, subMap);
                    if (unifyResult.Failure)
                    {
                        continue;
                    }
                    allFailed = false;
                    if (unifyResult.Changed)
                    {
                        return(GetCombinedAtoms(termB, termA, unifyResult));
                    }
                    atomToAdd = new Atom
                    {
                        Name         = "",
                        Arguments    = null,
                        IsBool       = true,
                        Truthfulness = (atomA.Truthfulness == atomB.Truthfulness)
                    };
                    break;
                }
                output.Add(atomToAdd);
                if (atomToAdd.IsBool && atomToAdd.Truthfulness)
                {
                    return(output);
                }
            }
            if (allFailed)
            {
                return(new List <Atom> {
                    new Atom
                    {
                        IsBool = true,
                        Truthfulness = true
                    }
                });
            }
            return(output);
        }
 public void ApplySubMap(SubstitutionMap subMap)
 {
     InnerLoop(Arguments, subMap);
 }
 private void Init()
 {
     Atoms  = new List <Atom>();
     SubMap = new SubstitutionMap();
 }