From 5fe8b9865cfbd7388b8f6355a73b1436d40cfb1e Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Thu, 22 Jul 2021 18:24:58 +0000 Subject: Make predicates private and static by default, and make them dynamic when using the dynamic/1 predicate --- builtins.c | 24 +++++++++++++++++------- loader.pl | 14 +++++++++++++- stdlib.pl | 4 +++- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/builtins.c b/builtins.c index b238ad6..43215f8 100644 --- a/builtins.c +++ b/builtins.c @@ -52,6 +52,7 @@ BuiltinProto(builtinclause); BuiltinProto(builtincurrentpredicate); BuiltinProto(builtinasserta); BuiltinProto(builtinassertz); +BuiltinProto(builtininsertclause); BuiltinProto(builtinretractone); BuiltinProto(builtinabolish); BuiltinProto(builtinatomlength); @@ -162,6 +163,8 @@ findbuiltin(Term *goal) 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 @@ builtincurrentpredicate(Term *goal, Binding **bindings, Module *module) } 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 @@ assertclause(Term *clause, Module *module, int after) 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 @@ assertclause(Term *clause, Module *module, int after) 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,14 +1179,21 @@ int builtinasserta(Term *goal, Binding **bindings, Module *module) { USED(bindings); - return assertclause(goal->children, module, 0); + return assertclause(goal->children, module, 0, 1); } int 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 @@ -1644,4 +1654,4 @@ builtinnewemptymodule(Term *goal, Binding **bindings, Module *module) Rune *name = goal->children->text; addemptymodule(name); return 1; -} \ No newline at end of file +} diff --git a/loader.pl b/loader.pl index 9126c1f..69fc2f9 100644 --- a/loader.pl +++ b/loader.pl @@ -70,8 +70,20 @@ handle_clause(Head, Body, Singletons, Module) :- 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) :- diff --git a/stdlib.pl b/stdlib.pl index 8640bdf..bca7e31 100644 --- a/stdlib.pl +++ b/stdlib.pl @@ -358,6 +358,8 @@ is_list(T) :- list(T), ! ; type_error(list, T). 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(Template, Goal, Instances) :- 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). -- cgit v1.2.3