Пример #1
0
            public bool Abolish(string functor, int arity)
            {
                string key = BaseTerm.MakeKey(functor, arity);

                if (predefineds.Contains(key))
                {
                    IO.Error("abolish of predefined predicate '{0}/{1}' not allowed", functor, arity);
                }

                PredicateDescr pd = this[key];

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

                predTable.Remove(key);

#if arg1index
                pd.DestroyFirstArgIndex(); // rebuilt by ResolveIndices()
#endif
                ResolveIndices();

                return(true);
            }
Пример #2
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();
 }
Пример #3
0
            public void AddPredicate(PredicateDescr pd)
            {
                // add predicate only if not already present
                int i = axis.BinarySearch(pd);

                if (i < 0)
                {
                    axis.Insert(~i, pd); // keep range sorted
                }
            }
Пример #4
0
            public bool ListClause(PredicateDescr pd, string functor, int arity, int seqno, out string outputString)
            {
                ClauseNode clause = null;
                string     details;
                var        sb = new StringBuilder();

                outputString = string.Empty;

                if ((clause = pd.ClauseList) == null)
                {
                    return(false);
                }

                details = "source: " + pd.DefiningFile;

                //        if (pd.IsFirstArgIndexed) details += "; arg1-indexed (jump points marked with '.')";

                sb.AppendFormat("\r\n{0}/{1}: ({2}) {3}", functor, arity, details,
                                ((seqno == 1) ? "" : (seqno.ToString().Packed())));
                sb.AppendLine();

                while (clause != null)
                {
                    bool currCachedClauseMustFail =
                        (clause is CachedClauseNode && !((CachedClauseNode)clause).Succeeds);

                    TermNode next;

                    //          // prefix a clause that is pointed to by first-argument indexing with '.'
                    //          IO.Write (" {0}{1}", (pd.IsFirstArgMarked (clause))?".":" ", nextClause.Term);
                    sb.AppendFormat("  {0}", clause.Term);

                    if (currCachedClauseMustFail)
                    {
                        sb.Append(" :- !, fail");
                    }
                    else if ((next = clause.NextNode) != null)
                    {
                        BI builtinId = next.BuiltinId;
                        sb.AppendFormat(" :-{0}", (builtinId == BI.none)
                    ? next.ToString()
                    : Environment.NewLine + builtinId.ToString());
                    }

                    sb.AppendLine(".");
                    clause = clause.NextClause;
                }

                outputString = sb.ToString();

                return(true);
            }
Пример #5
0
 // find all predicates that call 'col'
 public IEnumerable <PredicateDescr> Col(PredicateDescr col)
 {
     foreach (PredicateDescr row in axis)
     {
         if ((result = this [row, col]) != null)
         {
             if (findAllCalls || result == false)
             {
                 yield return(col);
             }
         }
     }
 }
Пример #6
0
            // put the predicate definition (if found) into the TermNode if it is not already there
            public bool FindPredicateDefinition(PredicateTable predicateTable)
            {
                if (predDescr == null)
                {
                    //IO.WriteLine ("predDescr == null for {0}", term.Name);
                    if ((predDescr = predicateTable [term.Key]) == null)
                    {
                        return(false);
                    }
                }

#if arg1index // first-argument indexing enabled
                BaseTerm arg;

                // caching would disturb the search process (since caching does not
                // cause the arg0Index to be rebuild, since this might be to costly)
                if (predDescr.IsFirstArgIndexed && !predDescr.HasCachedValues)
                {
                    if ((arg = term.Arg(0)).IsVar)
                    {
                        nextClause = predDescr.FirstArgVarClause();
                    }
                    else // not a variable
                    {
                        nextClause = predDescr.FirstArgNonvarClause(arg.FunctorToString);

                        // check whether there is an indexed var clause
                        if (nextClause == null)
                        {
                            nextClause = predDescr.FirstArgVarClause();
                        }

                        // if the above failed, the entire predicate fails (no unification possible)
                        if (nextClause == null)
                        {
                            nextClause = ClauseNode.FAIL;
                        }
                    }

                    if (nextClause == null)
                    {
                        nextClause = predDescr.ClauseList;
                    }
                }
                else // not indexed
#endif
                nextClause = predDescr.ClauseList;

                return(true);
            }
Пример #7
0
            // used only when registering the direct calls, not for the closure (indirect calls)
            public bool?this [PredicateDescr row, PredicateDescr col]
            {
                set
                {
                    this [CompoundKey(row, col)] = false; // i.e. a direct call
                }

                get
                {
                    if (TryGetValue(CompoundKey(row, col), out result))
                    {
                        return(result);
                    }

                    return(null);
                }
            }
Пример #8
0
            PredicateDescr SetClauseList(string f, int a, ClauseNode c)
            {
                string         key = BaseTerm.MakeKey(f, a);
                PredicateDescr pd  = this[key];

                if (pd == null)
                {
                    this[key] = pd =
                        new PredicateDescr(null, ConsultFileName, f, a, c);
                }
                else
                {
                    pd.SetClauseListHead(c);
                }

                pd.AdjustClauseListEnd();

                return(pd);
            }
Пример #9
0
            // try to match the name of an unrecognised command
            public PredicateDescr FindClosestMatch(string predName)
            {
                const float    THRESHOLD         = 0.5F; // maximum value for likely match
                PredicateDescr closestMatch      = null;
                float          closestMatchValue = 1.0F;

                foreach (KeyValuePair <string, PredicateDescr> kv in predTable)
                {
                    PredicateDescr pd = kv.Value;
                    float          matchValue;

                    if ((matchValue = pd.Name.Levenshtein(predName)) < closestMatchValue)
                    {
                        closestMatchValue = matchValue;
                        closestMatch      = pd;
                    }
                }

                return((closestMatchValue < THRESHOLD) ? closestMatch : null);
            }
Пример #10
0
            public void AddPredefined(ClauseNode clause)
            {
                BaseTerm       head = clause.Head;
                string         key  = head.Key;
                PredicateDescr pd   = this[key];

                if (pd == null)
                {
                    predefineds[key] = true;                                 // any value != null will do
                    SetClauseList(head.FunctorToString, head.Arity, clause); // create a PredicateDescr
                }
                else if (prevIndex != null && key != prevIndex)
                {
                    IO.Error("Definition for predefined predicate '{0}' must be contiguous", head.Index);
                }
                else
                {
                    pd.AppendToClauseList(clause);
                }

                prevIndex = key;
            }
Пример #11
0
            void ResolveIndex(PredicateDescr pd)
            {
                ClauseNode clause = pd.ClauseList;

                while (clause != null)                 // iterate over all clauses of this predicate. NextClause.BaseTerm contains predicate clauseHead
                {
                    BaseTerm clauseHead = clause.Head; // clause = clauseHead :- clauseTerm*
                    TermNode clauseTerm = clause.NextNode;

                    while (clauseTerm != null) // non-facts only. Iterate over all clauseTerm-terms at of this clause
                    {
                        if (clauseTerm.BuiltinId == BI.none)
                        {
                            clauseTerm.PredDescr = this[clauseTerm.Term.Key];
                        }
                        // builtins (>=0) are handled differently (in Execute ())

                        clauseTerm = clauseTerm.NextNode;
                    }
                    clause = clause.NextClause;
                }
                return;
            }
Пример #12
0
            void FindUndefined(SortedList sd, PredicateDescr pd)
            {
                ClauseNode clause = pd.ClauseList;
                TermNode   clauseTerm;

                while (clause != null) // iterate over all clauses of this predicate
                {
                    clauseTerm = clause.NextNode;

                    while (clauseTerm != null) // non-facts only. Iterate over all clauseTerm-terms of this clause
                    {
                        if (clauseTerm.BuiltinId == BI.none && clauseTerm.PredDescr == null)
                        {
                            sd[clauseTerm.Term.Index] = null;
                        }

                        clauseTerm = clauseTerm.NextNode;
                    }

                    clause = clause.NextClause;
                }

                return;
            }
Пример #13
0
 public TermNode(BaseTerm term, PredicateDescr predDescr, int level)
 {
     this.term      = term;
     this.predDescr = predDescr;
     this.level     = level;
 }
Пример #14
0
 public TermNode(BaseTerm term, PredicateDescr predDescr)
 {
     this.predDescr = predDescr;
     this.term      = term;
 }
Пример #15
0
            public bool ShowHelp(string functor, int arity, out string suggestion)
            {
                suggestion = null;
                const string HELPRES = "CsProlog.CsPrologHelp";

                // NOTE: .NET3.5+ can retrieve Assembly from a Type object via "Type.Assembly" property, but .NET Standard 1.4 dose not support it.
                var assemblyName = string.Join(", ", GetType().AssemblyQualifiedName.Split(',').Skip(1).Select(s => s.Trim()).ToArray());
                var asm          = Assembly.Load(new AssemblyName(assemblyName));
                var rm           = new ResourceManager(HELPRES, asm);

                if (functor == null)
                {
                    IO.WriteLine(rm.GetString("help$"));
                    IO.WriteLine("\r\n  (*) contains the description of a feature rather than a predicate.");
                    IO.WriteLine("\r\n  Usage: help <predicate>[/<arity>] or help( <predicate>[/<arity>]).");

                    return(true);
                }
                else if (functor == "history")
                {
                    IO.Write(HistoryHelpText);

                    return(true);
                }

                string[] arities;

                if (arity == -1)                                      // no arity given: show all predicates for 'functor'
                {
                    arities = new string[] { rm.GetString(functor) }; // returns something like "/0/2/3"

                    if (arities[0] == null)
                    {
                        return(false);
                    }

                    if (arities[0] == "(*)") // a little hacky
                    {
                        arities[0] = "*";
                    }
                    else
                    {
                        arities = arities[0].Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                    }
                }
                else
                {
                    arities = new string[] { arity.ToString() }
                };

                bool          found = false;
                StringBuilder sb    = new StringBuilder();
                string        content;

                foreach (string a in arities)
                {
                    string key = functor + '/' + a;
                    content = rm.GetString(key);

                    if (content == null)
                    {
                        break;
                    }

                    sb.AppendLine(content.TrimEnd());
                    found = true;
                }

                const string DASHES =
                    "  -------------------------------------------------------------------------------------------";


                if (found)
                {
                    IO.WriteLine("\r\n{0}\r\n{1}\r\n{0}", DASHES, sb.ToString());
                }
                else
                {
                    PredicateDescr pd = FindClosestMatch(functor + (arity > 0 ? '/' + arity.ToString() : null));
                    suggestion =
                        (pd == null) ? null : string.Format(" Maybe '{0}' is what you mean?", pd.Name);
                }

                return(found);
            }
Пример #16
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);
            }
Пример #17
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);
            }
Пример #18
0
            public void AddClause(ClauseNode clause)
            {
                BaseTerm head = clause.Head;

                string key   = head.Key;
                string index = head.Index;

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

                if (prevIndex == key) // previous clause was for the same predicate
                {
                    PredicateDescr pd = this[key];
                    pd.AppendToClauseList(clause);
                }
                else // first predicate or different predicate
                {
                    PredicateDescr pd = this[key];

                    if (!definedInCurrFile.Contains(key)) //  very first clause of this predicate in this file -- reset at start of consult
                    {
                        if (pd != null && pd.DefinitionFile != ConsultFileName)
                        {
                            IO.Error("Predicate '{0}' is already defined in {1}", index, pd.DefinitionFile);
                        }

                        definedInCurrFile[key] = true;
                        pd = SetClauseList(head.FunctorToString, head.Arity, clause); // implicitly erases all previous definitions
                        pd.IsDiscontiguous = (isDiscontiguous.Contains(key) || allDiscontiguous);
                        prevIndex          = key;
                    }
                    else // not the first clause. First may be from another definitionFile (which is an error).
                    {    // If from same, IsDiscontiguous must hold, unless DiscontiguousAllowed = "1" in .config
                        bool b = false;

                        if (pd.IsDiscontiguous || (b = ConfigSettings.DiscontiguousAllowed))
                        {
                            if (b)
                            {
                                IO.Warning("Predicate '{0}' is defined discontiguously but is not declared as such", index);
                            }

                            if (pd.DefinitionFile == ConsultFileName)
                            {
                                pd.AppendToClauseList(clause);
                            }
                            else // OK
                            {
                                IO.Error("Discontiguous predicate {0} must be in one file (also found in {1})", index, pd.DefinitionFile);
                            }
                        }
                        else if (pd.DefinitionFile == ConsultFileName) // Warning or Error?
                        {
                            IO.Error("Predicate '{0}' occurs discontiguously but is not declared as such", index);
                        }
                        else
                        {
                            IO.Error("Predicate '{0}' is already defined in {1}", index, pd.DefinitionFile);
                        }
                    }
                }
            }
Пример #19
0
            public bool ShowHelp(string functor, int arity, out string suggestion)
            {
                suggestion = null;
                const string HELPRES = "CsProlog.CsPrologHelp";

                Assembly asm = Assembly.GetExecutingAssembly();
                //string [] res = asm.GetManifestResourceNames (); // pick the right functor from res and put in in HELPRES
                ResourceManager rm = new ResourceManager(HELPRES, asm, null);

                if (functor == null)
                {
                    IO.WriteLine(rm.GetString("help$"));
                    IO.WriteLine("\r\n  (*) contains the description of a feature rather than a predicate.");
                    IO.WriteLine("\r\n  Usage: help <predicate>[/<arity>] or help( <predicate>[/<arity>]).");
                    IO.WriteLine("\r\n  File CsPrologHelp.txt contains the help texts and a description of how to re-create help.");

                    return(true);
                }
                else if (functor == "history")
                {
                    IO.Write(HistoryHelpText);

                    return(true);
                }

                string [] arities;

                if (arity == -1)                                       // no arity given: show all predicates for 'functor'
                {
                    arities = new string [] { rm.GetString(functor) }; // returns something like "/0/2/3"

                    if (arities [0] == null)
                    {
                        return(false);
                    }

                    if (arities [0] == "(*)") // a little hacky
                    {
                        arities [0] = "*";
                    }
                    else
                    {
                        arities = arities [0].Split(new char [] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                    }
                }
                else
                {
                    arities = new string [] { arity.ToString() }
                };

                bool          found = false;
                StringBuilder sb    = new StringBuilder();
                string        content;

                foreach (string a in arities)
                {
                    string key = functor + '/' + a;
                    content = rm.GetString(key);

                    if (content == null)
                    {
                        break;
                    }

                    sb.AppendLine(content.TrimEnd());
                    found = true;
                }

                const string DASHES =
                    "  -------------------------------------------------------------------------------------------";


                if (found)
                {
                    IO.WriteLine("\r\n{0}\r\n{1}\r\n{0}", DASHES, sb.ToString());
                }
                else
                {
                    PredicateDescr pd = FindClosestMatch(functor + (arity > 0 ? '/' + arity.ToString() : null));
                    suggestion =
                        (pd == null) ? null : string.Format(" Maybe '{0}' is what you mean?", pd.Name);
                }

                return(found);
            }
Пример #20
0
 string CompoundKey(PredicateDescr row, PredicateDescr col)
 {
     return(string.Format("{0} {1}", row.Name, col.Name));
 }