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); }
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(); }
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 } }
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); }
// 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); } } } }
// 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); }
// 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); } }
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); }
// 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); }
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; }
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; }
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; }
public TermNode(BaseTerm term, PredicateDescr predDescr, int level) { this.term = term; this.predDescr = predDescr; this.level = level; }
public TermNode(BaseTerm term, PredicateDescr predDescr) { this.predDescr = predDescr; this.term = term; }
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); }
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); }
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); }
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); } } } }
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); }
string CompoundKey(PredicateDescr row, PredicateDescr col) { return(string.Format("{0} {1}", row.Name, col.Name)); }