Dynamic Rule Approval in a SWI Prolog

I am trying to add a rule dynamically to the knowledge base using a SWI prolog where the body of the rule is not known in advance.

The desired rule looks something like this:

rule(a) :- fact(1), fact(2). 

Usually you just specify

 assert((rule(a):-fact(1),fact(2))). 

but the problem is that the facts are resolved at runtime (the number of facts is also unknown before the statement).

That is why I would like to know if it is possible to state a rule when the body consists of a list of facts, such as [fact (1), fact (2)]

+7
prolog
source share
2 answers

We will create a rule newrule(X) :- w,x,y,z(X) .
The body of the rule is a tuple, a construction in the form of (w, x, y ...).

For different body lengths, starting without a body:

 assert(goal). assert(goal:-cond). assert(goal:-(cond1,cond2)). 

The tuple operator is a comma (`, '), as in', '(a, b) == (a, b).

 %%%% %%%% Name: runtime.pl -- Runtime rule insertion. %%%% create_a_rule :- Cond=[w,x,y,z(X)], Head=newrule(X), list_to_tuple(Cond,Body), dynamic(Head), assert(Head :- Body), listing(Head). /* This is a [l,i,s,t], and this is a (t,u,p,l,e). Convertng list to tuple: [] -> undefined [x] -> (x) == x [x,y] -> (x,y). [x,y,z..whatever] = (x,y,z..whatever) */ list_to_tuple([],_) :- ValidDomain='[x|xs]', Culprit='[]', Formal=domain_error(ValidDomain, Culprit), Context=context('list_to_tuple','Cannot create empty tuple!'), throw(error(Formal,Context)). list_to_tuple([X],X). list_to_tuple([H|T],(H,Rest_Tuple)) :- list_to_tuple(T,Rest_Tuple). :- create_a_rule. :- listing(newrule). 

-

There are two lists. The first list from listing() is called in create_a_rule() . The second list from the listing() command on the last line of the source.

 ?- [runtime]. :- dynamic newrule/1. newrule(A) :- w, x, y, z(A). :- dynamic newrule/1. newrule(A) :- w, x, y, z(A). % runtime compiled 0.01 sec, 1,448 bytes true. 
+4
source share

Suggested change to frayser list:

 list_to_tuple([X],X). list_to_tuple([A,B],(A,B)). list_to_tuple([A,B|T],(A,B,Rest_Tuple)) :- list_to_tuple(T,Rest_Tuple). 

These conditions eliminate the need for an exception if the first variable is an empty list: it just fails. It also means that you will never hit the statement when you retreat.

However, nevertheless, you WANT a proposal for an exception, so you can still catch it when attempts were made to merge with []. (However, he will not hit him when he is returned).

+1
source share

All Articles