diff options
author | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-07-03 21:16:58 +0000 |
---|---|---|
committer | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-07-03 21:16:58 +0000 |
commit | 3f26a0f2a1f699e628136ec5be6178b5ab40fc44 (patch) | |
tree | 5f288b697076387d59111a5731dfdfeec380c447 | |
parent | 66a7040df6897e60ee1a513b95f4b04e687bbf0a (diff) |
Make the goalstack global just like the choicestack
-rw-r--r-- | builtins.c | 107 | ||||
-rw-r--r-- | dat.h | 5 | ||||
-rw-r--r-- | eval.c | 46 | ||||
-rw-r--r-- | repl.c | 2 |
4 files changed, 69 insertions, 91 deletions
@@ -5,14 +5,14 @@ #include "dat.h" #include "fns.h" -#define BuiltinProto(name) int name(Term *, Term *, Goal **, Binding **) +#define BuiltinProto(name) int name(Term *, Term *, Binding **) #define Match(X, Y) (runestrcmp(name, X) == 0 && arity == Y) #define Throw(What) do{\ Goal *g = malloc(sizeof(Goal)); \ g->goal = What; \ g->catcher = nil; \ - g->next = *goals; \ - *goals = g; \ + g->next = goalstack; \ + goalstack = g; \ return 1; \ }while(0) @@ -128,17 +128,16 @@ findbuiltin(Term *goal) } int -builtinfail(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinfail(Term *database, Term *goal, Binding **bindings) { USED(database); USED(goal); - USED(goals); USED(bindings); return 0; } int -builtincall(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtincall(Term *database, Term *goal, Binding **bindings) { USED(database); USED(bindings); @@ -146,17 +145,16 @@ builtincall(Term *database, Term *goal, Goal **goals, Binding **bindings) Goal *g = malloc(sizeof(Goal)); g->goal = goal->children; g->catcher = nil; - g->next = *goals; - *goals = g; + g->next = goalstack; + goalstack = g; return 1; } int -builtincut(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtincut(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Choicepoint *cp = choicestack; @@ -171,80 +169,72 @@ builtincut(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtinvar(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinvar(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *arg = goal->children; return (arg->tag == VariableTerm); } int -builtinatom(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinatom(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *arg = goal->children; return (arg->tag == AtomTerm); } int -builtininteger(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtininteger(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *arg = goal->children; return (arg->tag == NumberTerm && arg->numbertype == NumberInt); } int -builtinfloat(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinfloat(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *arg = goal->children; return (arg->tag == NumberTerm && arg->numbertype == NumberFloat); } int -builtinatomic(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinatomic(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *arg = goal->children; return (arg->tag == AtomTerm || arg->tag == NumberTerm); } int -builtincompound(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtincompound(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *arg = goal->children; return (arg->tag == CompoundTerm); } int -builtinnonvar(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinnonvar(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *arg = goal->children; return (arg->tag != VariableTerm); } int -builtinnumber(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinnumber(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *arg = goal->children; return (arg->tag == NumberTerm); @@ -306,10 +296,9 @@ compareterms(Term *t1, Term *t2) } int -builtincompare(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtincompare(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); Term *order = goal->children; Term *t1 = order->next; Term *t2 = t1->next; @@ -328,10 +317,9 @@ builtincompare(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtinfunctor(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinfunctor(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); Term *term = goal->children; Term *name = term->next; @@ -366,10 +354,9 @@ builtinfunctor(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtinarg(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinarg(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); Term *n = goal->children; Term *term = n->next; @@ -403,10 +390,9 @@ listlength(Term *term) } int -builtinuniv(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinuniv(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); Term *term = goal->children; Term *list = term->next; @@ -477,10 +463,9 @@ aritheval(Term *expr) } int -builtinis(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinis(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); Term *result = goal->children; Term *expr = result->next; @@ -493,7 +478,7 @@ builtinis(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtincatch(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtincatch(Term *database, Term *goal, Binding **bindings) { USED(database); USED(bindings); @@ -505,30 +490,29 @@ builtincatch(Term *database, Term *goal, Goal **goals, Binding **bindings) Goal *catchframe = malloc(sizeof(Goal)); catchframe->goal = recover; catchframe->catcher = catcher; - catchframe->next = *goals; - *goals = catchframe; + catchframe->next = goalstack; + goalstack = catchframe; Goal *g = malloc(sizeof(Goal)); g->goal = catchgoal; g->catcher = nil; - g->next = *goals; - *goals = g; + g->next = goalstack; + goalstack = g; return 1; } int -builtinthrow(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinthrow(Term *database, Term *goal, Binding **bindings) { USED(database); USED(bindings); - USED(goals); Term *ball = goal->children; print("Throwing: %S\n", prettyprint(ball, 0, 0, 0)); Goal *g; - for(g = *goals; g != nil; g = g->next){ + for(g = goalstack; g != nil; g = g->next){ if(g->catcher == nil) continue; @@ -539,12 +523,12 @@ builtinthrow(Term *database, Term *goal, Goal **goals, Binding **bindings) exits("exception"); return 0; }else{ - *goals = g->next; + goalstack = g->next; Goal *newgoal = malloc(sizeof(Goal)); newgoal->goal = copyterm(g->goal, nil); newgoal->catcher = nil; - newgoal->next = *goals; - *goals = newgoal; + newgoal->next = goalstack; + goalstack = newgoal; applybinding(newgoal->goal, *bindings); Choicepoint *cp = choicestack; @@ -559,17 +543,16 @@ builtinthrow(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtincurrentprologflag(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtincurrentprologflag(Term *database, Term *goal, Binding **bindings) { USED(database); USED(goal); - USED(goals); USED(bindings); return 0; } int -builtinsetprologflag(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinsetprologflag(Term *database, Term *goal, Binding **bindings) { USED(database); USED(bindings); @@ -589,10 +572,9 @@ builtinsetprologflag(Term *database, Term *goal, Goal **goals, Binding **binding } int -builtinopen(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinopen(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *sourcesink = goal->children; @@ -626,10 +608,9 @@ builtinopen(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtinclose(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinclose(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *stream = goal->children; @@ -653,10 +634,9 @@ builtinclose(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtincurrentinput(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtincurrentinput(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *stream = goal->children; @@ -668,10 +648,9 @@ builtincurrentinput(Term *database, Term *goal, Goal **goals, Binding **bindings } int -builtincurrentoutput(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtincurrentoutput(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *stream = goal->children; @@ -683,10 +662,9 @@ builtincurrentoutput(Term *database, Term *goal, Goal **goals, Binding **binding } int -builtinsetinput(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinsetinput(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *stream = goal->children; @@ -707,10 +685,9 @@ builtinsetinput(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtinsetoutput(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinsetoutput(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *stream = goal->children; @@ -731,10 +708,9 @@ builtinsetoutput(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtinreadterm(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinreadterm(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *stream = goal->children; @@ -763,10 +739,9 @@ builtinreadterm(Term *database, Term *goal, Goal **goals, Binding **bindings) } int -builtinwriteterm(Term *database, Term *goal, Goal **goals, Binding **bindings) +builtinwriteterm(Term *database, Term *goal, Binding **bindings) { USED(database); - USED(goals); USED(bindings); Term *stream = goal->children; @@ -2,7 +2,7 @@ typedef struct Term Term; typedef struct Binding Binding; typedef struct Goal Goal; typedef struct Choicepoint Choicepoint; -typedef int (*Builtin)(Term *, Term *, Goal **, Binding **); +typedef int (*Builtin)(Term *, Term *, Binding **); struct Term { @@ -67,4 +67,5 @@ enum { int flagdoublequotes; /* Staate of the running system */ -Choicepoint *choicestack;
\ No newline at end of file +Choicepoint *choicestack; +Goal *goalstack;
\ No newline at end of file @@ -16,8 +16,6 @@ static uvlong clausenr; int evalquery(Term *database, Term *query, Binding **resultbindings) { - Goal *goals; - if(choicestack == nil){ /* The goal stack has the original query at the very bottom, protected by a catch frame where the ->goal field is nil. @@ -25,34 +23,38 @@ evalquery(Term *database, Term *query, Binding **resultbindings) 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; + goalstack = malloc(sizeof(Goal)); + goalstack->goal = copyterm(query, nil); + goalstack->catcher = nil; + goalstack->next = nil; Goal *protector = malloc(sizeof(Goal)); protector->goal = nil; protector->catcher = mkvariable(L"catch-var"); - protector->next = goals; - goals = protector; + protector->next = goalstack; + goalstack = protector; /* Now add the actual goals */ - goals = addgoals(goals, query); + goalstack = addgoals(goalstack, 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){ + while(goalstack->goal != nil){ Term *dbstart; Term *goal; + Goal *oldgoalstack; dbstart = database; Retry: - goal = goals->goal; + print("Loop run\n"); + goal = goalstack->goal; + oldgoalstack = goalstack; + goalstack = goalstack->next; - if(goals->catcher){ - goals = goals->next; + if(oldgoalstack->catcher){ + print("Was catchframe\n"); continue; } @@ -61,11 +63,11 @@ Retry: Binding *bindings = nil; Term *clause = nil; - + /* Try to see if the goal can be solved using a builtin first */ Builtin builtin = findbuiltin(goal); if(builtin != nil){ - int success = builtin(database, goal, &goals->next, &bindings); + int success = builtin(database, goal, &bindings); if(!success) goto Backtrack; }else{ @@ -75,7 +77,7 @@ Retry: if(clause->next != nil){ /* Add a choicepoint. Note we create a choicepoint every time, so there is room for improvement. */ Choicepoint *cp = malloc(sizeof(Choicepoint)); - cp->goalstack = copygoals(goals); + cp->goalstack = copygoals(oldgoalstack); cp->next = choicestack; cp->retryclause = clause->next; cp->id = clause->clausenr; @@ -90,17 +92,15 @@ Backtrack: Choicepoint *cp = choicestack; choicestack = cp->next; /* freegoals(goals) */ - goals = cp->goalstack; + goalstack = cp->goalstack; dbstart = cp->retryclause; goto Retry; } } - - goals = goals->next; /* Apply bindings to all goals on the stack except catchframes */ Goal *g; - for(g = goals; g != nil; g = g->next){ + for(g = goalstack; g != nil; g = g->next){ if(g->goal != nil && g->catcher == nil) applybinding(g->goal, bindings); } @@ -109,11 +109,11 @@ Backtrack: if(clause != nil && clause->tag == CompoundTerm && clause->arity == 2 && runestrcmp(clause->text, L":-") == 0){ Term *subgoal = copyterm(clause->children->next, nil); applybinding(subgoal, bindings); - goals = addgoals(goals, subgoal); + goalstack = addgoals(goalstack, subgoal); } } - goals = goals->next; - unify(query, goals->goal, resultbindings); + goalstack = goalstack->next; + unify(query, goalstack->goal, resultbindings); return 1; } @@ -15,6 +15,8 @@ repl(Term *database) print("?- "); Term *query = parse(fd, nil, 1); Binding *bindings = nil; + choicestack = nil; + goalstack = nil; /* should free old choicestack and goalstack */ int success; FindMore: success = evalquery(database, query, &bindings); |