/// <summary> /// Fills in fields given head and body terms. /// </summary> protected KnowledgeBaseRule(Structure ruleHead, Structure[] ruleBody, bool checkSingletons, string source, int line) { SourceFile = source; SourceLineNumber = line; head = ruleHead; if (ruleHead == null) { throw new ArgumentNullException("ruleHead"); } HeadArgs = ruleHead.Arguments; headIndexers = PredicateArgumentIndexer.ArglistIndexers(HeadArgs); BodyGoals = ruleBody; FreeVariables = new List <LogicVariable>(); var singletons = new List <LogicVariable>(); foreach (var a in HeadArgs) { FindVariables(a, singletons); } foreach (var g in BodyGoals) { FindVariables(g, singletons); } if (checkSingletons && singletons.Count > 0) { foreach (var v in singletons) { PrintWarning("singleton variable: {0}", v.Name); } } Functor = ruleHead.Functor; }
/// <summary> /// Tests clauses in a randomized order (but still exhaustively). /// Uses Shuffler to generate a random permutation. /// </summary> IEnumerable <CutState> TestShuffledClauses(object[] args, PrologContext context, ushort myFrame) { entriesListUsed = true; var mark = context.MarkTrace(); var shuffler = new Shuffler((ushort)Entries.Count); var argIndexers = PredicateArgumentIndexer.ArglistIndexers(args); while (!shuffler.Done) { var entry = Entries[shuffler.Next()]; if (entry.Prematch(argIndexers)) { // This shouldn't be here... //context.PushGoalStack(Name, args, myFrame); context.SetCurrentRule(entry); foreach (var cutState in entry.Prove(args, context, myFrame)) { if (cutState == CutState.ForceFail) { if (KnowledgeBase.Trace || Trace) { context.TraceOutput("Cut: {0}", new Structure(Name, args)); } goto fail; } if (KnowledgeBase.Trace || Trace) { context.TraceOutput("Succeed: {0}", new Structure(Name, args)); } yield return(CutState.Continue); if (KnowledgeBase.Trace || Trace) { context.TraceOutput("Retry: {0}", new Structure(Name, args)); } } } } fail: context.RestoreVariables(mark); if (KnowledgeBase.Trace || Trace) { context.TraceOutput("Fail: {0}", new Structure(Name, args)); } //context.UnwindStack(Name, args); context.UnwindStack(myFrame); }
/// <summary> /// Tests clauses in the order they appear in the database. /// </summary> IEnumerable <CutState> TestClausesInOrder(object[] args, PrologContext context, ushort myFrame) { var mark = context.MarkTrace(); var argIndexers = PredicateArgumentIndexer.ArglistIndexers(args); entriesListUsed = true; foreach (var entry in Entries) { if (entry.Prematch(argIndexers)) { context.SetCurrentRule(entry); foreach (var cutState in entry.Prove(args, context, myFrame)) { if (cutState == CutState.ForceFail) { if (KnowledgeBase.Trace || Trace) { context.TraceOutput("Cut: {0}", new Structure(Name, args)); } goto fail; } if (KnowledgeBase.Trace || Trace) { context.TraceOutput("Succeed: {0}", new Structure(Name, args)); } yield return(CutState.Continue); if (KnowledgeBase.Trace || Trace) { context.TraceOutput("Retry: {0}", new Structure(Name, args)); } } } } fail: context.RestoreVariables(mark); if (KnowledgeBase.Trace || Trace) { context.TraceOutput("Fail: {0}", new Structure(Name, args)); } //context.UnwindStack(Name, args); context.UnwindStack(myFrame); }