shithub: pprolog

Download patch

ref: 58e0109ee9ed3aa6ac2e6b0ed621820118a3d1de
parent: 2dce50fbd5ef72bbcd51533cf04f8722f8139d6a
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Wed Jul 7 21:40:24 EDT 2021

Add clause/2 predicate

--- a/builtins.c
+++ b/builtins.c
@@ -47,6 +47,7 @@
 BuiltinProto(builtinreadterm);
 BuiltinProto(builtinwriteterm);
 BuiltinProto(builtingeq);
+BuiltinProto(builtinclause);
 
 int compareterms(Term *, Term *);
 
@@ -130,6 +131,8 @@
 		return builtinwriteterm;
 	if(Match(L">=", 2))
 		return builtingeq;
+	if(Match(L"clause", 3))
+		return builtinclause;
 
 	return nil;
 }
@@ -808,4 +811,53 @@
 		return aval->dval >= bval->ival;
 	else
 		return 0;
+}
+
+int
+builtinclause(Term *goal, Binding **bindings, Module *module)
+{
+	Term *head = goal->children;
+	Term *body = head->next;
+	Term *clauselist = body->next;
+	
+	if(head->tag == VariableTerm)
+		Throw(instantiationerror());
+	if(head->tag != AtomTerm && head->tag != CompoundTerm)
+		Throw(typeerror(L"callable", head));
+	if(body->tag != VariableTerm && body->tag != AtomTerm && body->tag != CompoundTerm)
+		Throw(typeerror(L"callable", body));
+	if(clauselist->tag != VariableTerm)
+		Throw(typeerror(L"variable", clauselist));
+
+	print("Attempting to find clauses in module %S where head unifies with %S\n", module->name, prettyprint(head, 0, 0, 0));
+
+	Predicate *pred = findpredicate(module->predicates, head);
+	if(pred == nil)
+		return 0;
+
+	Term *functor = mkatom(pred->name);
+	functor->next = mkinteger(pred->arity);
+	Term *pi = mkcompound(L"/", 2, functor);
+	if(!pred->public)
+		Throw(permissionerror(L"access", L"private_procedure", pi));
+
+	Term *realclauses = nil;
+	Clause *c = pred->clauses;
+	while(c != nil){
+		Binding *bs = nil;
+		c = findclause(c, head, &bs);
+		if(c != nil){
+			/* Append the clause to the realclauselist */
+			Term *cl = c->head;
+			if(c->body)
+				cl->next = c->body;
+			else
+				cl->next = mkatom(L"true");
+			
+			realclauses = appendterm(realclauses, mkcompound(L"clause", 2, cl));
+			c = c->next;
+		}
+	}
+	Term *realclauselist = mklist(realclauses);
+	return unify(clauselist, realclauselist, bindings);
 }
\ No newline at end of file
--- a/dat.h
+++ b/dat.h
@@ -51,7 +51,6 @@
 	Term *head;
 	Term *body;
 	uvlong clausenr;
-	int public;
 	Clause *next;
 };
 
@@ -59,6 +58,7 @@
 {
 	Rune *name;
 	int arity;
+	int public;
 	Clause *clauses;
 	Predicate *next;
 };
--- a/eval.c
+++ b/eval.c
@@ -5,8 +5,6 @@
 #include "dat.h"
 #include "fns.h"
 
-Predicate *findpredicate(Predicate *, Term *);
-Clause *findclause(Clause *, Term *, Binding **);
 int equalterms(Term *, Term *);
 Goal *copygoals(Goal *);
 Builtin findbuiltin(Term *);
@@ -142,9 +140,6 @@
 {
 	Clause *clause;
 	for(; clauses != nil; clauses = clauses->next){
-		if(!clauses->public)
-			continue;
-
 		clause = copyclause(clauses, &clausenr);
 		clausenr++;
 		clause->next = clauses->next;
@@ -209,6 +204,7 @@
 			b->value = right;
 			b->next = *bindings;
 			*bindings = b;
+
 			Term *t;
 			for(t = leftstack; t != nil; t = t->next)
 				applybinding(t, b);
--- a/fns.h
+++ b/fns.h
@@ -22,6 +22,8 @@
 int unify(Term *, Term *, Binding **);
 void applybinding(Term *, Binding *);
 Goal *addgoals(Goal *, Term *, Module *);
+Predicate *findpredicate(Predicate *, Term *);
+Clause *findclause(Clause *, Term *, Binding **);
 
 /* repl.c */
 void repl(void);
--- a/lists.pl
+++ b/lists.pl
@@ -7,10 +7,6 @@
 	length(Tail, Length0),
 	Length is Length0 + 1.
 
-member(X, [X|_]).
-member(X, [_|Tail]) :-
-	member(X, Tail).
-
 append([], Ys, Ys).
 append([X|Xs], Ys, [X|Rest]) :-
 	append(Xs, Ys, Rest).
--- a/misc.c
+++ b/misc.c
@@ -152,7 +152,6 @@
 		new->clausenr = *clausenr;
 	else
 		new->clausenr = orig->clausenr;
-	new->public = orig->public;
 	new->next = nil;
 	return new;
 }
\ No newline at end of file
--- a/module.c
+++ b/module.c
@@ -59,7 +59,6 @@
 		Clause *cl = malloc(sizeof(Clause));
 		int arity;
 		cl->clausenr = 0;
-		cl->public = 1; /* everything is public for now */
 		cl->next = nil;
 		if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 2){
 			cl->head = t->children;
@@ -83,6 +82,7 @@
 			currentpred->name = cl->head->text;
 			currentpred->arity = arity;
 			currentpred->clauses = cl;
+			currentpred->public = 1; /* everything is public for now */
 			currentpred->next = nil;
 		}else
 			currentpred->clauses = appendclause(currentpred->clauses, cl);
--- a/stdlib.pl
+++ b/stdlib.pl
@@ -150,3 +150,13 @@
 	E2 < E1.
 
 
+% Clause retrieval and information
+
+clause(Head, Body) :-
+	clause(Head, Body, Clauses),
+	member(clause(Head, Body), Clauses).
+
+% Basic list predicates
+member(X, [X|_]).
+member(X, [_|Tail]) :-
+	member(X, Tail).