summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/eval.c b/eval.c
index e28e5e6..ae34175 100644
--- a/eval.c
+++ b/eval.c
@@ -7,7 +7,6 @@
Goal *addgoals(Goal *, Term *);
Term *findclause(Term *, Term *, Binding **);
int equalterms(Term *, Term *);
-void applybinding(Term *, Binding *);
Goal *copygoals(Goal *);
Builtin findbuiltin(Term *);
@@ -21,16 +20,18 @@ evalquery(Term *database, Term *query, Binding **resultbindings, Choicepoint **r
if(choicestack == nil){
/*
- The goal stack has the original query at the very bottom, protected by a goal there the ->goal field is nil.
+ The goal stack has the original query at the very bottom, protected by a catch frame where 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->catcher = nil;
goals->next = nil;
Goal *protector = malloc(sizeof(Goal));
protector->goal = nil;
+ protector->catcher = mkvariable(L"catch-var");
protector->next = goals;
goals = protector;
@@ -50,6 +51,11 @@ evalquery(Term *database, Term *query, Binding **resultbindings, Choicepoint **r
Retry:
goal = goals->goal;
+ if(goals->catcher){
+ goals = goals->next;
+ continue;
+ }
+
if(debug)
print("Working goal: %S\n", prettyprint(goal));
@@ -81,7 +87,6 @@ Backtrack:
return 0;
if(debug)
print("Backtracking..\n");
-
Choicepoint *cp = choicestack;
choicestack = cp->next;
/* freegoals(goals) */
@@ -93,10 +98,10 @@ Backtrack:
goals = goals->next;
- /* Apply bindings to all goals on the stack. */
+ /* Apply bindings to all goals on the stack except catchframes */
Goal *g;
for(g = goals; g != nil; g = g->next){
- if(g->goal != nil)
+ if(g->goal != nil && g->catcher == nil)
applybinding(g->goal, bindings);
}
@@ -122,6 +127,7 @@ addgoals(Goal *goals, Term *t)
}else{
Goal *g = malloc(sizeof(Goal));
g->goal = t;
+ g->catcher = nil;
g->next = goals;
goals = g;
}
@@ -266,6 +272,10 @@ copygoals(Goal *goals)
g->goal = copyterm(goals->goal, nil);
else
g->goal = nil;
+ if(goals->catcher)
+ g->catcher = copyterm(goals->catcher, nil);
+ else
+ g->catcher = nil;
g->next = copygoals(goals->next);
return g;
}else