shithub: pprolog

Download patch

ref: 347e5bc533070a5e988d82e7588a4e905c7096f3
parent: 8fde6e4845eeafe6ffc4179218a3ac9e8049c0e6
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Wed Jun 30 10:15:49 EDT 2021

Give queries another id than clauses, so variable names doesn't clash

--- a/TODO
+++ b/TODO
@@ -4,3 +4,4 @@
 4) Stop copying the entire goal stack into every choicepoint
 5) Stop creating choicepoints when it is not needed
 6) How to implement builtins nicely?
+7) Right now we copy and allocate a lot, but almost never free stuff.
\ No newline at end of file
--- a/eval.c
+++ b/eval.c
@@ -35,7 +35,7 @@
 	Goal *goals;
 	Choicepoint *choicestack = nil;
 
-	clausenr = 0;
+	clausenr = 2; /* Start at two since 0 is for the facts in the database, and 1 is for queries */
 
 	/*
 		The goal stack has the original query at the very bottom, protected by a goal there the ->goal field is nil.
@@ -128,8 +128,8 @@
 	Term *clause;
 	Term *head;
 	for(; database != nil; database = database->next){
-		clausenr++;
 		clause = copyterm(database, &clausenr);
+		clausenr++;
 		clause->next = database->next;
 		if(clause->tag == CompoundTerm && runestrcmp(clause->text, L":-") == 0 && clause->arity == 2)
 			head = clause->children;
@@ -215,9 +215,10 @@
 
 	switch(a->tag){
 	case AtomTerm:
-	case VariableTerm:
 	case StringTerm:
 		return !runestrcmp(a->text, b->text);
+	case VariableTerm:
+		return (runestrcmp(a->text, b->text) == 0 && a->clausenr == b->clausenr);
 	case NumberTerm:
 		if(a->numbertype != b->numbertype)
 			return 0;
--- a/parser.c
+++ b/parser.c
@@ -90,7 +90,12 @@
 	initoperators();
 	nexttoken();
 
-	return prologtext(querymode);
+	Term *result = prologtext(querymode);
+	if(querymode){
+		uvlong id = 1;
+		result = copyterm(result, &id);
+	}
+	return result;
 }
 
 Term *