我打算在数据库中描述“规则是可交换的”,直接的想法是像代码一样。
certain_rule(X,Y) :- X = struct(_X,Others) , Y = some_process_base_on(_X).
certain_rule(Y,X) :- X = struct(_X,Others) , Y = some_process_base_on(_X).
但是如果X
是未绑定的,它将使X
直接与struct(_X,Others)
绑定,那么some_process_base_on(_X)
将是未知的。现在,我的解决方案是在故障compound(X)
之前插入X
。
通常,compound/1
不够严格,会采取一些意想不到的方法,functor/3
可能是更好的解决方案,但是由于存在太多需要比较的函子,即使存在很多函子,也会存在太多规则使用member/2
在列表中找到函子,但我仍然构造了太多组合。
有没有更好的方法来描述“可交换”,顺便说一句,有没有更好的方法来筛选掉某些指定的结构?
答案 0 :(得分:1)
首先,请注意,您的子句等同于编写:
certain_rule(struct(X,_), some_process_base_on(X)).
certain_rule(some_process_base_on(X), struct(X,_)).
屏幕的有效结构的一种可能解决方案是使用有效结构的表。例如:
valid_structure(-) :-
!,
fail.
valid_structure(struct(_,_)).
valid_structure(some_process_base_on(_)).
...
第一个子句将筛选出变量,同时保留该谓词的第一参数索引。然后,您可以定义 gatekeeper 谓词:
certain_rule_gatekeeper(X, Y) :-
once((valid_structure(X); valid_structure(Y))),
certain_rule(X, Y).
要解决可交换性,在您的特定情况下是否可以使用以下定义?
certain_rule_gatekeeper(X, Y) :-
once((valid_structure(X); valid_structure(Y))),
once((certain_rule(X, Y); certain_rule(Y, X))).
仅对certain_rule/2
谓词使用上述子句之一进行采样调用(从而避免重复信息):
| ?- certain_rule_gatekeeper(X, Y).
no
| ?- certain_rule_gatekeeper(struct(X,_), Y).
Y = some_process_base_on(X)
yes
| ?- certain_rule_gatekeeper(Y, struct(X,_)).
Y = some_process_base_on(X)
yes
| ?- certain_rule_gatekeeper(some_process_base_on(X), Y).
Y = struct(X,_)
yes
| ?- certain_rule_gatekeeper(Y, some_process_base_on(X)).
Y = struct(X,_)
yes