コード例 #1
0
            public override bool Unify(BaseTerm t, VarStack varStack)
            {
                NextUnifyCount();

                if (!((t = t.ChainEnd()) is ListPatternElem))
                {
                    return(false);                                          // should never occur
                }
#if old
                if (isNegSearch != ((ListPatternElem)t).isNegSearch)
                {
                    return(false);
                }
#endif
                for (int i = 0; i < arity; i++)
                {
                    if (!((args[i] == null && t.Args[i] == null) ||
                          args[i].Unify(t.Args[i], varStack)))
                    {
                        return(false);
                    }
                }

                return(true);
            }
コード例 #2
0
            public override bool Unify(BaseTerm t, VarStack varStack)
            {
                if ((t = t.ChainEnd()) is Variable) // t not unified
                {
                    ((Variable)t).Bind(this);
                    varStack.Push(t);

                    return(true);
                }

                if (t is ListPatternTerm && arity == t.Arity) // two ListPatternTerms match if their rangeTerms match
                {
                    for (int i = 0; i < arity; i++)
                    {
                        if (!args[i].Unify(t.Args[i], varStack))
                        {
                            return(false);
                        }
                    }

                    return(true);
                }

                if (t is ListTerm)
                {
                    pattern = args;                   // pattern is searched ...
                    target  = ((ListTerm)t).ToList(); // ... in target
                    int ip = 0;
                    int it = 0;

                    return(UnifyTailEx(ip, it, varStack));
                }

                return(false);
            }
コード例 #3
0
            public static bool SetWorkingDirectory(BaseTerm term, VarStack varStack)
            {
                if (term.Arity == 0)
                {
                    workingDirectory = GetConfigSetting("WorkingDirectory", null);
                    IO.Message("Working directory set to '{0}'", WorkingDirectory);

                    return(true);
                }

                BaseTerm t0 = term.Arg(0);

                if (t0.IsVar)
                {
                    t0.Unify(new StringTerm(workingDirectory), varStack); // symbolic names

                    return(true);
                }

                string wd = Utils.DirectoryNameFromTerm(t0);

                if (wd == null)
                {
                    IO.Error("Illegal name '{0}' for working directory", t0.FunctorToString);

                    return(false);
                }

                workingDirectory = wd;
                IO.Message("Working directory set to '{0}'", WorkingDirectory);

                return(true);
            }
コード例 #4
0
            public override bool Unify(BaseTerm t, VarStack varStack)
            {
                if (t is Variable)
                {
                    return(t.Unify(this, varStack));
                }

                NextUnifyCount();
                const double eps = 1.0e-6; // arbitrary, cosmetic

                if (t is DecimalTerm)
                {
                    return(Math.Abs(im) < eps &&
                           Math.Abs(re - ((DecimalTerm)t).ValueD) < eps);
                }

                if (t is ComplexTerm)
                {
                    return(Math.Abs(re - ((ComplexTerm)t).Re) < eps &&
                           Math.Abs(im - ((ComplexTerm)t).Im) < eps);
                }

                //if (t is ComplexTerm)
                //  return ( re == ((ComplexTerm)t).Re && im == ((ComplexTerm)t).Im );

                return(false);
            }
コード例 #5
0
 public ClauseIterator(PredicateTable predTable, BaseTerm clauseHead, VarStack varStack)
 {
     this.pd         = predTable[clauseHead.Key]; // null if not found
     this.clauseHead = clauseHead;
     this.varStack   = varStack;
     iterator        = GetEnumerator();
 }
コード例 #6
0
ファイル: BaseTerm.cs プロジェクト: sandhaka/CSharpProlog
            public bool IsUnifiableWith(BaseTerm t, VarStack varStack) // as Unify, but does not actually bind
            {
                int  marker = varStack.Count;
                bool result = Unify(t, varStack);

                UnbindToMarker(varStack, marker);

                return(result);
            }
コード例 #7
0
 public NodeIterator(BaseTerm root, BaseTerm pattern,
                     BaseTerm minLenTerm, BaseTerm maxLenTerm, BaseTerm path, VarStack varStack)
 {
     this.root       = root;
     this.pattern    = pattern;
     this.varStack   = varStack;
     this.minLenTerm = minLenTerm;
     this.maxLenTerm = maxLenTerm;
     this.path       = path;
     iterator        = GetEnumerator();
 }
コード例 #8
0
ファイル: BaseTerm.cs プロジェクト: sandhaka/CSharpProlog
            public static void UnbindToMarker(VarStack varStack, int marker)
            {
                for (int i = varStack.Count - marker; i > 0; i--) // unbind all vars that got bound by Unify
                {
                    Variable v = varStack.Pop() as Variable;

                    if (v != null)
                    {
                        v.Unbind();
                    }
                }
            }
コード例 #9
0
ファイル: Heap.cs プロジェクト: markpwns1/Dormez
        public Variable DeclareGlobalVariable(string name, DObject val)
        {
            if (variables.ContainsKey(name))
            {
                throw new InterpreterException(interpreter.CurrentToken, "Global variable already exists: " + name);
            }

            var stack = new VarStack();
            var v     = new Variable(val, -1);

            stack.Push(v);
            variables.Add(name, stack);
            return(v);
        }
コード例 #10
0
ファイル: BaseTerm.cs プロジェクト: sandhaka/CSharpProlog
            public static string VarList(VarStack varStack) // debugging only
            {
                StringBuilder result = new StringBuilder();

                foreach (object v in varStack.ToArray())
                {
                    if (v != null && v is Variable)
                    {
                        result.AppendLine(string.Format(">> {0} = {1}", ((Variable)v).Name, (Variable)v));
                    }
                }

                return(result.ToString());
            }
コード例 #11
0
ファイル: Heap.cs プロジェクト: markpwns1/Dormez
        public ReadOnlyVariable DeclareReadOnly(string name, DObject val)
        {
            var v = new ReadOnlyVariable(val, interpreter.depth);

            if (!variables.ContainsKey(name))
            {
                var stack = new VarStack();
                stack.Push(v);
                variables.Add(name, stack);
            }

            variables[name].Push(v);

            return(v);
        }
コード例 #12
0
ファイル: Event.variable.cs プロジェクト: 7474/SRC
 public IEnumerable <VarData> SubLocalVars()
 {
     if (CallDepth > 0)
     {
         int i = VarIndexStack[CallDepth - 1];
         return(VarStack.Skip(i + 1).Take(VarIndex - i));
     }
     else if (VarIndex > 0)
     {
         return(VarStack.Take(VarIndex + 1));
     }
     else
     {
         return(Enumerable.Empty <VarData>());
     }
 }
コード例 #13
0
ファイル: Heap.cs プロジェクト: markpwns1/Dormez
        public Variable DeclareLocal(string name, DObject val)
        {
            val = val == null ? DUndefined.instance : val;

            var v = new Variable(val, interpreter.depth);

            if (!variables.ContainsKey(name))
            {
                var stack = new VarStack();
                stack.Push(v);
                variables.Add(name, stack);
            }

            variables[name].Push(v);

            return(v);
        }
コード例 #14
0
            private AltLoopStatus TryOneAlternative(int ip, VarStack varStack, ListPatternElem e, int k,
                                                    int marker, ListTerm RangeList, int i, BaseTerm t, ref bool negSearchSucceeded, BaseTerm searchTerm)
            {
                bool unified = searchTerm.Unify(t, varStack);

                if (e.IsNegSearch) // none of the terms in the inner loop may match. ~(a | b | c) = ~a & ~b & ~c
                {
                    if (unified)   // ... no point in investigating the other alternatives if one does
                    {
                        negSearchSucceeded = false;

                        return(AltLoopStatus.Break); // don't try the other alternatives
                    }

                    return(AltLoopStatus.TryNextDown); // non of the downranges matches may lead to a success
                }
                else
                {
                    if (unified &&                                                    // we found a match. Unify, and
                        TryBindingAltListVarToMatch(e.AltListBindVar, t, varStack) && // bind the AltListBindVar to the match
                        TryBindingRangeRelatedVars(e, i, RangeList, varStack))        // bind the range to the range variables
                    {
                        if (ip == pattern.Length - 1)                                 // this was the last pattern element
                        {
                            if (k == target.Count - 1)                                // both pattern and target exhausted
                            {
                                return(AltLoopStatus.MatchFound);
                            }
                        }
                        else if (UnifyTailEx(ip + 1, k + 1, varStack)) // now deal with the rest
                        {
                            return(AltLoopStatus.MatchFound);
                        }
                    }

                    // if we arrive here, it was not possible to ...
                    // (1) ... unify the range's SearchTerm with the target element, or
                    // (2) ... unify the range variable with the range list, or
                    // (3) ... successfully process the rest of the pattern and target
                    // Now unbind and try matching with the next target element
                    BaseTerm.UnbindToMarker(varStack, marker);

                    return(AltLoopStatus.TryNextDown); // try the next downrange match
                }
            }
コード例 #15
0
ファイル: BaseTerm.cs プロジェクト: sandhaka/CSharpProlog
            // UNIFICATION
            // The stack is used to store the variables and choice points that are bound
            // by the unification. This is required for backtracking. Unify does not do
            // any unbinding in case of failure. This will be done during backtracking.
            // refUnifyCount: can be used for calculating the 'cost' of a predicate Call
            public virtual bool Unify(BaseTerm t, VarStack varStack)
            {
                NextUnifyCount();

                if (t.IsUnified)
                {
                    return(this.Unify(t.ChainEnd(), varStack));
                }

                if (t is Variable) // t not unified
                {
                    ((Variable)t).Bind(this);
                    varStack.Push(t);

                    return(true);
                }

                if (t is ListPatternTerm)
                {
                    return(t.Unify(this, varStack));
                }

                if (termType != t.termType)
                {
                    return(false);                        // gives a slight improvement
                }
                if (functor.Equals(t.functor) && arity == t.arity)
                {
                    for (int i = 0; i < arity; i++)
                    {
                        if (!args[i].Unify(t.args[i], varStack))
                        {
                            return(false);
                        }
                    }

                    return(true);
                }

                return(false);
            }
コード例 #16
0
ファイル: BaseTerm.cs プロジェクト: sandhaka/CSharpProlog
 public void NumberVars(ref int k, VarStack s)
 {
     if (IsVar)
     {
         this.Unify(new CompoundTerm(NUMVAR, new DecimalTerm(k++)), s);
     }
     else
     {
         if (IsUnified)
         {
             ChainEnd().NumberVars(ref k, s);
         }
         else if (arity != 0) // nonvar & not isUnified
         {
             for (int i = 0; i < arity; i++)
             {
                 args[i].NumberVars(ref k, s);
             }
         }
     }
 }
コード例 #17
0
            // try to bind the variable associated with the list of search alternatives
            // (t1|t2|...|tn) to the target term found matching one of these alternatives
            bool TryBindingAltListVarToMatch(BaseTerm AltListVar, BaseTerm searchTerm, VarStack varStack)
            {
                if (AltListVar == null)
                {
                    return(true);
                }

                return(AltListVar.Unify(searchTerm, varStack));
            }
コード例 #18
0
            // each call processes one element of pattern[]
            bool UnifyTailEx(int ip, int it, VarStack varStack)
            {
                ListPatternElem e            = (ListPatternElem)pattern[ip];
                Variable        rangeSpecVar = (Variable)e.RangeBindVar;
                NodeIterator    subtreeIterator;
                int             k;
                int             marker;
                ListTerm        RangeList = null;
                BaseTerm        tail      = null;
                int             minLen; // minimum required range length (number of range elements)
                int             maxLen; // maximum possible ...

                if (!DoLowerAndUpperboundChecks(ip, it, out minLen, out maxLen))
                {
                    return(false);
                }

                // scan the minimal number of range elements. Add them to the range list,
                // i.e. the last variable (if present) preceding the '{ , }'
                for (int i = 0; i < minLen; i++)
                {
                    if ((k = it + i) >= target.Count)
                    {
                        return(false);
                    }

                    AppendToRangeList(ref RangeList, rangeSpecVar, target[k], ref tail);
                }

                marker = varStack.Count; // register the point to which we must possibly undo unifications

                if (e.HasSearchTerm)
                {
                    // scan the elements up to the maximum range length, and the element immediately thereafter
                    for (int i = minLen; i <= maxLen; i++)
                    {
                        BaseTerm t = null;
                        k = it + i;

                        if (k == target.Count)
                        {
                            return(false);
                        }

                        bool negSearchSucceeded = true;         // iff none of the alternative term matches the target term

                        for (int j = 4; j < e.Args.Length; j++) // scan all AltSearchTerm alternatives (separated by '|')
                        {
                            BaseTerm      searchTerm    = e.AltSearchTerms[j];
                            DownRepFactor downRepFactor = null; // e.downRepFactor [j];
                            t = target[k];
                            AltLoopStatus status = AltLoopStatus.TryNextAlt;

                            if (downRepFactor == null)
                            {
                                status =
                                    TryOneAlternative(ip, varStack, e, k, marker, RangeList, i, t, ref negSearchSucceeded, searchTerm);

                                if (status == AltLoopStatus.MatchFound)
                                {
                                    return(true);
                                }
                            }
                            else // traverse the downRepFactor tree, which in principle may yield more than one match
                            {
                                subtreeIterator = new NodeIterator(t, searchTerm, downRepFactor.minLenTerm,
                                                                   downRepFactor.maxLenTerm, false, downRepFactor.bindVar, varStack);

                                foreach (BaseTerm match in subtreeIterator) // try -- if necessary -- each tree match with the current search term
                                {
                                    status =
                                        TryOneAlternative(ip, varStack, e, k, marker, RangeList, i, match, ref negSearchSucceeded, searchTerm);

                                    if (status == AltLoopStatus.MatchFound)
                                    {
                                        return(true);
                                    }

                                    if (status == AltLoopStatus.Break)
                                    {
                                        break;
                                    }
                                }
                            }

                            if (status == AltLoopStatus.Break)
                            {
                                break;
                            }
                        }

                        // at this point sufficient alternatives have been tried
                        if (e.IsNegSearch && negSearchSucceeded)                               // none of the terms matched => ok if binding succeeds
                        {
                            if (!TryBindingAltListVarToMatch(e.AltListBindVar, t, varStack) || // bind the AltListBindVar to the match
                                !TryBindingRangeRelatedVars(e, i, RangeList, varStack))        // bind the range to the range variables
                            {
                                return(false);                                                 // binding failed
                            }
                            if (ip == pattern.Length - 1)                                      // this was the last pattern element
                            {
                                if (k == target.Count - 1)                                     // both pattern and target exhausted
                                {
                                    return(true);
                                }
                            }
                            else if (UnifyTailEx(ip + 1, k + 1, varStack)) // now deal with the rest
                            {
                                return(true);
                            }
                        }
                        else if (i < maxLen) // append the rejected term to the range list and go try the next term
                        {
                            AppendToRangeList(ref RangeList, rangeSpecVar, t, ref tail);
                        }
                    }
                }
                else // a range without a subsequent search term (so followed by another range or end of pattern)
                {
                    for (int i = minLen; i <= maxLen; i++)
                    {
                        k = it + i;

                        if (k == target.Count)                                             // ok, target[k] does not exist, end of target hit
                        {
                            return(TryBindingRangeRelatedVars(e, i, RangeList, varStack)); // i is actual range length
                        }
                        // k is ok
                        if (i < maxLen)
                        {
                            AppendToRangeList(ref RangeList, rangeSpecVar, target[k], ref tail);
                        }

                        // now deal with the rest
                        if (TryBindingRangeRelatedVars(e, i, RangeList, varStack) &&
                            UnifyTailEx(ip + 1, k, varStack))
                        {
                            return(true);
                        }
                    }
                }

                // If we arrive here, no matching term was found in or immediately after the permitted range.
                // Therefore, undo any unifications made locally in this method and return with failure.
                if (marker != 0)
                {
                    BaseTerm.UnbindToMarker(varStack, marker);
                }

                return(false);
            }
コード例 #19
0
            public bool Retract(BaseTerm t, VarStack varStack, BaseTerm where)
            {
                string key = t.Key;

                if (predefineds.Contains(key))
                {
                    IO.Error("retract of predefined predicate {0} not allowed", key);
                }

                PredicateDescr pd = this[key];

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

                InvalidateCrossRef();
                ClauseNode c     = pd.ClauseList;
                ClauseNode prevc = null;
                BaseTerm   cleanTerm;
                int        top;

                while (c != null)
                {
                    cleanTerm = c.Head.Copy();

                    top = varStack.Count;

                    if (cleanTerm.Unify(t, varStack))     // match found -- remove this term from the chain
                    {
                        if (prevc == null)                // remove first clause
                        {
                            if (c.NextClause == null)     // we are about to remove the last remaining clause for this predicate
                            {
                                predTable.Remove(key);    // ... so remove its PredicateDescr as well
#if arg1index
                                pd.CreateFirstArgIndex(); // re-create
#endif
                                ResolveIndices();
                            }
                            else
                            {
                                pd.SetClauseListHead(c.NextClause);
                            }
                        }
                        else // not the first
                        {
                            prevc.NextClause = c.NextClause;
                            prevc            = c;
                            pd.AdjustClauseListEnd();
#if arg1index
                            pd.CreateFirstArgIndex(); // re-create
#endif
                        }

                        return(true); // possible bindings must stay intact (e.g. if p(a) then retract(p(X)) yields X=a)
                    }

                    Variable s;
                    for (int i = varStack.Count - top; i > 0; i--) // unbind all vars that got bound by the above Unification
                    {
                        s = (Variable)varStack.Pop();
                        s.Unbind();
                    }

                    prevc = c;
                    c     = c.NextClause;
                }

                ResolveIndices();

                return(false);
            }
コード例 #20
0
            public bool RetractAll(BaseTerm t, VarStack varStack)
            {
                // remark: first-argument indexing is not affected by deleting clauses

                string key = t.Key;

                if (predefineds.Contains(key))
                {
                    IO.Error("retract of predefined predicate {0} not allowed", key);
                }

                PredicateDescr pd = this[key];

                if (pd == null)
                {
                    return(true);
                }

                ClauseNode c     = pd.ClauseList;
                ClauseNode prevc = null;
                bool       match = false;

                while (c != null)
                {
                    BaseTerm cleanTerm = c.Term.Copy();

                    if (cleanTerm.IsUnifiableWith(t, varStack)) // match found -- remove this head from the chain
                    {
                        match = true;                           // to indicate that at least one head was found

                        if (prevc == null)                      // remove first clause
                        {
                            if (c.NextClause == null)           // we are about to remove the last remaining clause for this predicate
                            {
                                predTable.Remove(key);          // ... so remove its PredicateDescr as well

                                break;
                            }
                            else
                            {
                                pd.SetClauseListHead(c.NextClause);
                            }
                        }
                        else // not the first
                        {
                            prevc.NextClause = c.NextClause;
                            prevc            = c;
                        }
                    }
                    else
                    {
                        prevc = c;
                    }

                    c = c.NextClause;
                }

                if (match)
                {
#if arg1index
                    pd.DestroyFirstArgIndex(); // rebuilt by ResolveIndices()
#endif
                    pd.AdjustClauseListEnd();
                    ResolveIndices();
                }

                return(true);
            }
コード例 #21
0
            // try to bind the range specification variable (if present) to the range list.
            // if the minimun or the maximum range length was a variable, then bind it to the actual length just found
            bool TryBindingRangeRelatedVars(ListPatternElem g, int rangeLength, ListTerm RangeList, VarStack varStack)
            {
                if (g.MinLenTerm.IsVar)
                {
                    g.MinLenTerm.Unify(new DecimalTerm(rangeLength), varStack);
                }

                if (g.MaxLenTerm.IsVar)
                {
                    g.MaxLenTerm.Unify(new DecimalTerm(rangeLength), varStack);
                }

                if (g.RangeBindVar != null)
                {
                    if (RangeList == null)
                    {
                        RangeList = ListTerm.EMPTYLIST;
                    }

                    if (!g.RangeBindVar.Unify(RangeList, varStack))
                    {
                        return(false); // alas, the same range var was apparently used & bound earlier in the pattern
                    }
                }

                return(true);
            }