public void SetClauseListHead (ClauseNode c) { clauseList = clauseListEnd = c; while (clauseListEnd.NextClause != null) clauseListEnd = clauseListEnd.NextClause; DestroyFirstArgIndex (); }
public PredicateDescr (string module, string definingFile, string functor, int arity, ClauseNode clauseList) { this.module = module; this.definingFile = (definingFile == null) ? "predefined or asserted predicate" : definingFile; this.functor = functor; this.arity = arity; #if enableSpying spyMode = SpyPort.None; #endif this.clauseList = clauseListEnd = clauseList; this.lastCachedClause = null; // no cached clauses (yet) }
public PredicateDescr(string m, string f, string n, int a, ClauseNode c) { module = m; definingFile = (f == null) ? "predefined or asserted predicate" : f; name = n; arity = a; #if debugging spyMode = SpyPort.none; #endif clauseList = clauseListEnd = c; // disqualify this predicate for first-argument indexing if arity=0 }
public void AppendToClauseList(ClauseNode c) // ClauseNode and ClauseListEnd are != null { clauseListEnd.NextClause = c; do clauseListEnd = clauseListEnd.NextClause; while (clauseListEnd.NextClause != null); #if arg1index DestroyFirstArgIndex (); #endif }
public void AdjustClauseListEnd() // forward clauseListEnd to the last clause { if ((clauseListEnd = clauseList) != null) while (clauseListEnd.NextClause != null) clauseListEnd = clauseListEnd.NextClause; }
public ProcedurePredDescr (string m, string f, string n, int a, ClauseNode c, bool s) : base (m, f, n, a, c) { isSelectable = s; }
// CACHEING CURRENTLY NOT USED #region Cacheing // Cache -- analogous to asserting a fact, but specifically for cacheing. // Cached terms are inserted at the very beginning of the predicate's clause // chain, in the order in which they were determined. public void Cache (BaseTerm cacheTerm, bool succeeds) { IO.WriteLine ("Cacheing {0}{1}", cacheTerm, succeeds ? null : " :- !, fail"); CachedClauseNode newCachedClause = new CachedClauseNode (cacheTerm, null, succeeds); if (lastCachedClause == null) // about to add the first cached term { newCachedClause.NextClause = clauseList; clauseList = newCachedClause; } else { newCachedClause.NextClause = lastCachedClause.NextClause; lastCachedClause.NextClause = newCachedClause; } lastCachedClause = newCachedClause; }
public void Clear() { term = null; nextNode = null; nextClause = null; level = 0; }
public void Assert(Term assertion, bool asserta) { assertion = assertion.CleanCopy(); // make a fresh copy Term head; TermNode body = null; if (assertion.Functor == Parser.IMPLIES) { head = assertion.Arg(0); body = assertion.Arg(1).ToGoalList(); } else head = assertion; if (head.IsVar) PrologIO.Error("Cannot assert a variable as predicate head"); string key = head.KbKey; // A predefined predicate (which may also be defined as operator) may not be redefined. // Operators ':-', ',', ';', '-->', '->' (precedence >= 1000) may also not be redefined. if (predefineds.Contains(key) || (head.Precedence >= 1000)) PrologIO.Error("assert cannot be applied to predefined predicate or system operator {0}", assertion.Index); PredicateDescr pd = (PredicateDescr)predTable[key]; #if persistent if (pd != null && pd is PersistentPredDescr) { ((PersistentPredDescr)pd).Assert (head); return; } #endif ClauseNode newC = new ClauseNode(head, body); if (pd == null) // first head { SetClauseList(PredEnum.session, head.Functor, head.Arity, newC); ResolveIndices(); } else if (asserta) // at beginning { newC.NextClause = pd.ClauseNode; // pd.ClauseNode may be null SetClauseList(PredEnum.session, head.Functor, head.Arity, newC); #if arg1index pd.CreateFirstArgIndex (); // re-create #endif } else // at end { pd.AppendToClauseList(newC); #if arg1index pd.CreateFirstArgIndex (); // re-create #endif } }
public void AddPredefined(ClauseNode clause) { Term Term = clause.Term; string key = Term.KbKey; PredicateDescr pd = this[key]; if (pd == null) { predefineds[key] = "true"; // any value != null will do SetClauseList(PredEnum.session, Term.Functor, Term.Arity, clause); // create a pd } else if (prevIndex != null && key != prevIndex) PrologIO.Error("Definition for predefined predicate '{0}' must be contiguous", Term.Index); else pd.AppendToClauseList(clause); prevIndex = key; }
public ClauseChoicePoint(TermNode g, ClauseNode c, ClauseNode nextClause) { goal = g; clause = c; active = true; this.nextClause = nextClause; }
private void ReadBuiltinPredicates() { //varStack.Clear (); ps.Reset(); parser.StreamIn = Builtins.Predicates; retractClause = ps[Term.Key("retract", 1)].GetClauseList(null, null); ps.ResolveIndices(); }
/* public ChoicePoint(TermNode g, ClauseNode c) { goal = g; clause = c; active = true; } */ public ChoicePoint(TermNode g, ClauseNode c, double cp) { goal = g; clause = c; active = true; currProb = cp; }
public bool IsFirstArgMarked (ClauseNode c) { if (arg0Index == null) return false; BaseTerm t = c.Term.Arg (0); ClauseNode result; if (t.IsVar) arg0Index.TryGetValue (VARARG, out result); else arg0Index.TryGetValue (t.FunctorToString, out result); return (result == c); }
public void Uncache () { if (HasCachedValues) // let clauseList start at the first non-cached clause again { clauseList = lastCachedClause.NextClause; lastCachedClause = null; } }
// whereTerm != null : for persistent predicates only // put the predicate definition (if found) into the TermNode if it is not already there public bool FindPredicateDefinition(PredicateStorage predicateStorage, Term whereTerm) { if (predDescr == null) predDescr = predicateStorage[term.KbKey]; if (predDescr == null) return false; #if arg1index Term arg; if (predDescr.IsFirstArgIndexed) { if ((arg = term.Arg (0)).IsVar) nextClause = predDescr.FirstArgVarClause (); else // not a variable { nextClause = predDescr.FirstArgNonvarClause (arg.Functor); // 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; // "fail." } if (nextClause == null) nextClause = predDescr.GetClauseList (term, whereTerm); // GetClauseList: in PredicateStorage } else // not indexed #endif nextClause = predDescr.GetClauseList(term, whereTerm); // GetClauseList: in PredicateStorage return true; }
private PredicateDescr SetClauseList(PredEnum predType, string f, int a, ClauseNode c) { string key = Term.Key(f, a); PredicateDescr pd = this[key]; if (pd == null) { switch (predType) { #if persistent case PredEnum.table: this [key] = pd = new TablePredDescr (Globals.ConsultModuleName, Globals.ConsultFileName, f, a, c); break; case PredEnum.selproc: this [key] = pd = new ProcedurePredDescr (Globals.ConsultModuleName, Globals.ConsultFileName, f, a, c, true); break; case PredEnum.execproc: this [key] = pd = new ProcedurePredDescr (Globals.ConsultModuleName, Globals.ConsultFileName, f, a, c, false); break; #endif default: if (f.Contains("::")) { String[] parts = Regex.Split(f, "::"); double prob = Double.Parse(parts[0], Globals.CI); long timestamp = 0L; string clauseText = ""; if (parts.Length == 3) { if ("T".Equals(parts[1])) { timestamp = DateTime.Now.Ticks; } else { timestamp = DateTime.Now.Ticks + long.Parse(parts[1]) *10000000; } clauseText = parts[2]; } else { clauseText = parts[1]; } Parser np = new Parser(null); np.StreamIn = clauseText + "."; Term goalTerm = np.QueryNode.Term; key = Term.Key(goalTerm.Functor, goalTerm.Arity); ClauseNode cn = new ClauseNode(goalTerm, null, prob, timestamp); if (this[key] == null) { this[key] = pd = new PredicateDescr(Globals.ConsultModuleName, Globals.ConsultFileName, goalTerm.Functor, goalTerm.Arity, cn); } else { pd = this[key]; pd.AppendToClauseList(cn); } } else { this[key] = pd = new PredicateDescr(Globals.ConsultModuleName, Globals.ConsultFileName, f, a, c); } break; } } else pd.SetClauseListHead(c); pd.AdjustClauseListEnd(); return pd; }
public bool IsFirstArgMarked (ClauseNode c) { if (arg0Index == null) return false; Term t = c.Term.Arg (0); return (t.IsVar) ? (arg0Index [VARARG] == c) : (arg0Index [t.Functor] == c); }
public void AddClause(ClauseNode clause) { Term Term = clause.Term; string key = Term.KbKey; string index = Term.Index; if (predefineds.Contains(key)) PrologIO.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[key] == null) // very first clause of this predicate in this file -- reset at start of consult { // check whether it was defined as persistent if (pd != null && pd.DefiningFile != Globals.ConsultFileName) { #if persistent if (pd is PersistentPredDescr) IO.Error ("No predicate definitions allowed for persistent predicate '{0}'", index); else #endif PrologIO.Error("Predicate '{0}' is already defined in {1}", index, pd.DefiningFile); } definedInCurrFile[key] = true; pd = SetClauseList(PredEnum.session, Term.Functor, Term.Arity, clause); // implicitly erases all previous definitions pd.IsDiscontiguous = (isDiscontiguous[key] != null || allDiscontiguous); // NOTE: SetClauseListHead does not reset all remaining fields in the possibly existing PredicateDescr -- look at this later prevIndex = key; } else // not the first clause. First may be from another definingFile (which is an error). If from same, IsDiscontiguous must hold { if (pd.IsDiscontiguous) { if (pd.DefiningFile == Globals.ConsultFileName) pd.AppendToClauseList(clause); else // OK PrologIO.Error("Discontiguous predicate {0} must be in one file (also found in {1})", index, pd.DefiningFile); } else if (pd.DefiningFile == Globals.ConsultFileName) // error PrologIO.Error("Predicate '{0}' occurs discontiguously but is not declared as such", index); else PrologIO.Error("Predicate '{0}' is already defined in {1}", index, pd.DefiningFile); } } }
public PersistentPredDescr (string m, string f, string n, int a, ClauseNode c) : base (m, f, n, a, c) { queriesTable = new Hashtable (); }
private void ClauseNode(TerminalSet _TS) { Term head; TermNode body = null; ClauseNode c; if (parseMode != ParseMode.Reading) Globals.EraseVariables(); GetSymbol(new TerminalSet(LeftParen, Identifier, IntLiteral, RealLiteral, StringLiteral, Operator, Atom, Anonymous, CutSym, ImpliesSym, PromptSym, LSqBracket, LCuBracket, PrologString), false, true); if (symbol.IsMemberOf(LeftParen, Identifier, IntLiteral, RealLiteral, StringLiteral, Operator, Atom, Anonymous, CutSym, LSqBracket, LCuBracket, PrologString)) { PrologTerm(new TerminalSet(Dot, ImpliesSym, DCGArrowSym), out head); if (!head.IsGoal) PrologIO.Error("Illegal predicate head: {0}", head.ToString()); GetSymbol(new TerminalSet(Dot, ImpliesSym, DCGArrowSym), false, true); if (symbol.IsMemberOf(ImpliesSym, DCGArrowSym)) { GetSymbol(new TerminalSet(ImpliesSym, DCGArrowSym), false, true); if (symbol.Terminal == ImpliesSym) { symbol.SetProcessed(); Query(new TerminalSet(Dot), out body); } else { symbol.SetProcessed(); Term t; PrologTerm(new TerminalSet(Dot), out t); body = t.ToDCG(ref head); } } c = new ClauseNode(head, body); if (parseMode == ParseMode.Reading) readTerm = new Term(c).CleanUp(); else ps.AddClause(c); } else if (symbol.Terminal == PromptSym) { symbol.SetProcessed(); bool m = inQueryMode; bool o = is1000OperatorSetting; int k = terminalTable[DOT]; try { parseMode = ParseMode.Query; inQueryMode = true; terminalTable[DOT] = Dot; Set1000Operators(true); Query(new TerminalSet(Dot), out queryNode); PrologIO.Error("'?-' querymode in file not yet supported"); } finally { inQueryMode = m; terminalTable[DOT] = k; Set1000Operators(o); } } else { symbol.SetProcessed(); terminalTable.Add(Persistent, "Persistent", "persistent"); terminalTable.Add(Module, "Module", "module"); terminalTable.Add(UndefPredAction, "UndefPredAction", "undef_pred_action"); try { GetSymbol(new TerminalSet(LSqBracket, OpSym, EnsureLoaded, Discontiguous, AllDiscontiguous, Dynamic, Persistent, Module, UndefPredAction), false, true); if (symbol.Terminal == OpSym) { OperatorDefinition(new TerminalSet(Dot), true); } else if (symbol.Terminal == EnsureLoaded) { symbol.SetProcessed(); GetSymbol(new TerminalSet(LeftParen), true, true); GetSymbol(new TerminalSet(StringLiteral, Atom), false, true); if (symbol.Terminal == Atom) { symbol.SetProcessed(); } else { symbol.SetProcessed(); } string fileName = Utils.ExtendedFileName(symbol.ToString().ToLower(), ".pl"); if (Globals.ConsultedFiles[fileName] == null) { ps.Consult(fileName); Globals.ConsultedFiles[fileName] = true; } GetSymbol(new TerminalSet(RightParen), true, true); } else if (symbol.Terminal == Discontiguous) { symbol.SetProcessed(); Term t; PrologTerm(new TerminalSet(Dot), out t); ps.SetDiscontiguous(t); } else if (symbol.Terminal == AllDiscontiguous) { symbol.SetProcessed(); ps.SetDiscontiguous(true); } else if (symbol.Terminal == UndefPredAction) { symbol.SetProcessed(); Term t; PrologTerm(new TerminalSet(Dot), out t); ps.SetUndefPredAction(t, true); } else if (symbol.Terminal == Dynamic) { symbol.SetProcessed(); Term t; PrologTerm(new TerminalSet(Dot), out t); } else if (symbol.Terminal == Persistent) { PersistentDeclaration(new TerminalSet(Dot)); } else if (symbol.Terminal == Module) { symbol.SetProcessed(); GetSymbol(new TerminalSet(LeftParen), true, true); try { terminalTable[COMMA] = Comma; GetSymbol(new TerminalSet(StringLiteral, Atom), false, true); if (symbol.Terminal == Atom) { symbol.SetProcessed(); } else { symbol.SetProcessed(); } ps.SetModuleName(symbol.ToString()); GetSymbol(new TerminalSet(Comma), true, true); } finally { terminalTable[COMMA] = Operator; } Term t; PrologTerm(new TerminalSet(RightParen), out t); GetSymbol(new TerminalSet(RightParen), true, true); } else { symbol.SetProcessed(); int lines = 0; int files = 0; try { while (true) { GetSymbol(new TerminalSet(StringLiteral, Atom), false, true); if (symbol.Terminal == Atom) { symbol.SetProcessed(); } else { symbol.SetProcessed(); } string fileName = Utils.FileNameFromSymbol(symbol.ToString(), ".pl"); terminalTable[COMMA] = Operator; lines += ps.Consult(fileName); files++; terminalTable[COMMA] = Comma; GetSymbol(new TerminalSet(Comma, RSqBracket), false, true); if (symbol.Terminal == Comma) { symbol.SetProcessed(); } else break; } if (files > 1) PrologIO.Message("Grand total is {0} lines", lines); } finally { terminalTable[COMMA] = Operator; } GetSymbol(new TerminalSet(RSqBracket), true, true); } } finally { terminalTable.Remove("module"); terminalTable.Remove("persistent"); terminalTable.Remove("undef_pred_action"); } } GetSymbol(new TerminalSet(Dot), true, true); }
public TablePredDescr (string m, string f, string n, int a, ClauseNode c) : base (m, f, n, a, c) { }
// 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; }
public Term(ClauseNode c) // Create a Term from a ClauseNode (= Head + Body) { if (c.NextNode == null) // fact { Term t = c.Term; _functor = t._functor; arity = t.arity; args = t.args; varNo = t.varNo; ULink = t.ULink; fType = t.fType; oType = t.oType; oDescr = t.oDescr; precedence = t.precedence; hasValue = t.hasValue; isUnified = t.isUnified; isPacked = t.isPacked; } else { _functor = Parser.IMPLIES; arity = 2; args = new Term[2]; args[0] = c.Term; fType = FType.comp; oType = OType.xfx; args[1] = TermSeq(c.NextNode); precedence = 1200; } }