summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <peter@pmikkelsen.com>2021-06-30 23:30:13 +0000
committerPeter Mikkelsen <peter@pmikkelsen.com>2021-06-30 23:30:13 +0000
commit85adea62d7e8eee9d0e3525d572325db4e58d21a (patch)
treee976789abf464f9868f9a12778285329db785d7a /eval.c
parentfa83d3f1aba932e99833244ebb38b7415b142bd7 (diff)
Allow the repl to backtrack to give alternative results
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/eval.c b/eval.c
index a3b1e87..e28e5e6 100644
--- a/eval.c
+++ b/eval.c
@@ -14,30 +14,33 @@ Builtin findbuiltin(Term *);
static uvlong clausenr;
int
-evalquery(Term *database, Term *query, Binding **resultbindings)
+evalquery(Term *database, Term *query, Binding **resultbindings, Choicepoint **resultchoicestack)
{
Goal *goals;
- Choicepoint *choicestack = nil;
-
- clausenr = 2; /* Start at two since 0 is for the facts in the database, and 1 is for queries */
+ Choicepoint *choicestack = *resultchoicestack;
+ if(choicestack == nil){
/*
The goal stack has the original query at the very bottom, protected by a goal there the ->goal field is nil.
This makes it so that we can continue until we hit the protective goal, at which point we have solved everything
and to get the result we can unify the original query with the one at the bottom of the stack, to get the bindings
applied.
*/
+ goals = malloc(sizeof(Goal));
+ goals->goal = copyterm(query, nil);
+ goals->next = nil;
+ Goal *protector = malloc(sizeof(Goal));
+ protector->goal = nil;
+ protector->next = goals;
+ goals = protector;
- goals = malloc(sizeof(Goal));
- goals->goal = copyterm(query, nil);
- goals->next = nil;
- Goal *protector = malloc(sizeof(Goal));
- protector->goal = nil;
- protector->next = goals;
- goals = protector;
+ /* Now add the actual goals */
+ goals = addgoals(goals, query);
- /* Now add the actual goals */
- goals = addgoals(goals, query);
+ clausenr = 2; /* Start at two since 0 is for the facts in the database, and 1 is for queries */
+ }else{
+ goto Backtrack;
+ }
while(goals->goal != nil){
Term *dbstart;
@@ -76,7 +79,9 @@ Retry:
Backtrack:
if(choicestack == nil)
return 0;
- print("Backtracking..\n");
+ if(debug)
+ print("Backtracking..\n");
+
Choicepoint *cp = choicestack;
choicestack = cp->next;
/* freegoals(goals) */
@@ -104,6 +109,7 @@ Backtrack:
}
goals = goals->next;
unify(query, goals->goal, resultbindings);
+ *resultchoicestack = choicestack;
return 1;
}