我正在尝试使用SWI-prolog动态地将规则添加到知识库中,其中规则的主体事先是未知的。
所需的规则如下所示:
rule(a) :- fact(1), fact(2).
通常你只需说明
assert((rule(a):-fact(1),fact(2))).
但问题是事实是在运行时决定的(在断言之前事实的数量也是未知的。)
这就是为什么我想知道是否有可能主张一个规则,其中正文包含一系列事实,如[fact(1),fact(2)]
答案 0 :(得分:5)
我们将创建一个规则newrule(X) :- w,x,y,z(X)
规则的主体是一个元组,一个(w,x,y ...)形式的构造。
对于不同的身体长度,从没有身体开始:
assert(goal).
assert(goal:-cond).
assert(goal:-(cond1,cond2)).
元组运算符是逗号(`,'),如','(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).
-
有两个列表。第一个列表来自listing()
中create_a_rule()
。第二个列表来自最后一个源代码行的listing()
命令。
?- [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.
答案 1 :(得分:1)
建议更改frayser的列表:
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).
如果第一个变量是空列表,则这些子句不需要异常:它只会失败。这也意味着你在回溯时永远不会打一个断言。
但是,您可能仍然希望使用异常条款,因此您仍然可以将其用于捕获尝试与[]进行统一的情况。 (但回溯时不会碰到它。)