shithub: pprolog

Download patch

ref: 5fe8b9865cfbd7388b8f6355a73b1436d40cfb1e
parent: fd10cf6997473226272b397b0ff6ebd87bd4d161
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Thu Jul 22 14:24:58 EDT 2021

Make predicates private and static by default, and make them dynamic when using the dynamic/1 predicate

--- a/builtins.c
+++ b/builtins.c
@@ -52,6 +52,7 @@
 BuiltinProto(builtincurrentpredicate);
 BuiltinProto(builtinasserta);
 BuiltinProto(builtinassertz);
+BuiltinProto(builtininsertclause);
 BuiltinProto(builtinretractone);
 BuiltinProto(builtinabolish);
 BuiltinProto(builtinatomlength);
@@ -162,6 +163,8 @@
 		return builtinasserta;
 	if(Match(L"assertz", 1))
 		return builtinassertz;
+	if(Match(L"$insert_clause", 1))
+		return builtininsertclause;
 	if(Match(L"retract_one", 1))
 		return builtinretractone;
 	if(Match(L"abolish", 1))
@@ -1103,7 +1106,7 @@
 }
 
 int
-assertclause(Term *clause, Module *module, int after)
+assertclause(Term *clause, Module *module, int after, int dynamic)
 {
 	/* If after=0 then this is asserta, else it is assertz */
 	Term *head;
@@ -1144,7 +1147,7 @@
 	Predicate *p;
 	for(p = module->predicates; p != nil; p = p->next){
 		if(p->arity == arity && runestrcmp(p->name, name) == 0){
-			if(!p->dynamic){
+			if(!p->dynamic && dynamic){
 				Term *t = mkatom(name);
 				t->next = mkinteger(arity);
 				Term *pi = mkcompound(L"/", 2, t);
@@ -1163,9 +1166,9 @@
 	p->name = name;
 	p->arity = arity;
 	p->clauses = cl;
-	p->public = 1;
+	p->public = dynamic;
 	p->builtin = 0;
-	p->dynamic = 1;
+	p->dynamic = dynamic;
 	p->next = nil;
 	module->predicates = appendpredicate(p, module->predicates);
 
@@ -1176,7 +1179,7 @@
 builtinasserta(Term *goal, Binding **bindings, Module *module)
 {
 	USED(bindings);
-	return assertclause(goal->children, module, 0);
+	return assertclause(goal->children, module, 0, 1);
 }
 
 int
@@ -1183,10 +1186,17 @@
 builtinassertz(Term *goal, Binding **bindings, Module *module)
 {
 	USED(bindings);
-	return assertclause(goal->children, module, 1);
+	return assertclause(goal->children, module, 1, 1);
 }
 
 int
+builtininsertclause(Term *goal, Binding **bindings, Module *module)
+{
+	USED(bindings);
+	return assertclause(goal->children, module, 1, 0);
+}
+
+int
 builtinretractone(Term *goal, Binding **bindings, Module *module)
 {
 	Term *clause = goal->children;
@@ -1644,4 +1654,4 @@
 	Rune *name = goal->children->text;
 	addemptymodule(name);
 	return 1;
-}
\ No newline at end of file
+}
--- a/loader.pl
+++ b/loader.pl
@@ -70,8 +70,20 @@
 	functor(Head, Name, Arity),
 	PredicateIndicator = Name / Arity,
 	warn_singletons(PredicateIndicator, Singletons),
-	Module:assertz(Head :- Body).
+	Module:'$insert_clause'(Head :- Body).
 
+handle_directive(dynamic(PI), Module, Module) :-
+	is_nonvar(PI),
+	( list(PI)
+	-> [First|Rest] = PI,
+	   handle_directive(dynamic(First), Module, Module),
+	   handle_directive(dynamic(Rest), Module, Module)
+	; is_predicate_indicator(PI),
+	  Name / Arity = PI,
+	  functor(Tmp, Name, Arity),
+	  Module:asserta(Tmp),
+	  Module:retract(Tmp)
+	).
 handle_directive(op(Priority, Specifier, Operator), Module, Module) :-
 	Module:op(Priority, Specifier, Operator).
 handle_directive(include(F), Module, NewModule) :-
--- a/stdlib.pl
+++ b/stdlib.pl
@@ -358,6 +358,8 @@
 
 is_integer(T) :- integer(T), ! ; type_error(integer, T).
 
+is_predicate_indicator(T) :- (nonvar(T), T = N/A, integer(A), atom(N), !) ; type_error(predicate_indicator, T).
+
 % All solutions
 
 findall(Template, Goal, Instances) :-
@@ -372,7 +374,7 @@
 	findall_collect([], Instances).
 
 findall_collect(Acc, Instances) :-
-	retract('find all'(Item)),
+	system:retract('find all'(Item)),
 	!,
 	findall_collect(Item, Acc, Instances).
 findall_collect([], Instances, Instances).