Esempio n. 1
0
        private static bool FindSubst(Name n1, Name n2, bool allowPartialTerms, SubstitutionSet bindings)
        {
            n1 = n1.MakeGround(bindings);
            n2 = n2.MakeGround(bindings);
            var t = GetTerms(n1, n2, allowPartialTerms);

            if (t == null)
            {
                return(false);
            }

            foreach (var p in t)
            {
                Substitution candidate = null;
                bool         isVar1    = p.Item1.IsVariable;
                bool         isVar2    = p.Item2.IsVariable;

                // Case 1: x = t, where t is not a variable and x is a variable, and create substitution x/t
                if (isVar1 != isVar2)
                {
                    Name variable = (isVar1 ? p.Item1 : p.Item2);
                    Name value    = isVar1 ? p.Item2 : p.Item1;
                    if (value.ContainsVariable(variable))                               //Occurs check to prevent cyclical evaluations
                    {
                        return(false);
                    }

                    candidate = new Substitution(variable, new ComplexValue(value));
                }
                else if (isVar1)                 //isVar1 == isVar2 == true
                {
                    //Case 2: x = x, where x is a variable, ignore it. otherwise add the substitution
                    if (!(p.Item1 == p.Item2))
                    {
                        candidate = new Substitution(p.Item1, new ComplexValue(p.Item2));
                    }
                }
                else                 //isVar1 == isVar2 == false
                {
                    // Case 3: t1 = t2, where t1,t2 are not variables.
                    // If they don't contain variables, compare them to see if they are equal. If they are not equal the unification fails.
                    if (p.Item1.IsGrounded && p.Item2.IsGrounded)
                    {
                        if (p.Item1 == p.Item2)
                        {
                            continue;
                        }
                        if (p.Item1 == Name.UNIVERSAL_SYMBOL || p.Item2 == Name.UNIVERSAL_SYMBOL)
                        {
                            continue;
                        }

                        return(false);
                    }

                    //If one or both contain variables, unify the terms
                    if (!FindSubst(p.Item1, p.Item2, allowPartialTerms, bindings))
                    {
                        return(false);
                    }
                }

                if (candidate != null)
                {
                    // Step 4: check to see if the newly created substitution conflicts with any of the already created substitution.
                    // If it does, the unification fails.
                    if (!bindings.AddSubstitution(candidate))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
 public override Name MakeGround(SubstitutionSet bindings)
 {
     return(this);
 }
Esempio n. 3
0
 /// <summary>
 /// Given a SubstitutionSet, tries to ground this Name by substituting every variable with the corresponding value.
 /// </summary>
 /// <param name="bindings">The SubstitutionSet to be used to ground this Name.</param>
 /// <returns>A new instance, which is a clone of this Name, but grounded as much as possible.</returns>
 /// <remarks>
 /// - If this instance is already grounded before calling this method, it will just return the same Name.
 /// - This method does not warrant that this Name will be fully grounded, as the given SubstitutionSet
 /// may not contain the substitution variables needed to perform the task.
 /// </remarks>
 public abstract Name MakeGround(SubstitutionSet bindings);