如何在序言中描述交换规则?

时间:2019-03-26 18:28:01

标签: prolog

我打算在数据库中描述“规则是可交换的”,直接的想法是像代码一样。

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在列表中找到函子,但我仍然构造了太多组合。

有没有更好的方法来描述“可交换”,顺便说一句,有没有更好的方法来筛选掉某些指定的结构?

1 个答案:

答案 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