ref: 3f26a0f2a1f699e628136ec5be6178b5ab40fc44
parent: 66a7040df6897e60ee1a513b95f4b04e687bbf0a
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Sat Jul 3 17:16:58 EDT 2021
Make the goalstack global just like the choicestack
--- a/builtins.c
+++ b/builtins.c
@@ -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 @@
}
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 @@
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,10 +169,9 @@
}
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);
@@ -181,10 +178,9 @@
}
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);
@@ -191,10 +187,9 @@
}
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);
@@ -201,10 +196,9 @@
}
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);
@@ -211,10 +205,9 @@
}
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);
@@ -221,10 +214,9 @@
}
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);
@@ -231,10 +223,9 @@
}
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);
@@ -241,10 +232,9 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
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 @@
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
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;
--- a/dat.h
+++ b/dat.h
@@ -2,7 +2,7 @@
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 @@
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
--- a/eval.c
+++ b/eval.c
@@ -16,8 +16,6 @@
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,18 +23,18 @@
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{
@@ -43,16 +41,20 @@
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 @@
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 @@
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 @@
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 @@
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;
}
--- a/repl.c
+++ b/repl.c
@@ -15,6 +15,8 @@
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);