动态谓词和区分大小写

时间:2017-02-21 16:37:37

标签: prolog

我写了以下代码:

:-dynamic [subjectHaveDomain/2].
:-dynamic [objectHaveDomain/2].  

element(X,[X|_]).             % Is X part of the list
element(X,[_|R]) :-
    element(X,R).     

subset([],_).                 % Is [X|R] a subset of K
subset([X|R],K) :-
    element(X,K),
    subset(R,K).

subjectHaveDomain(S,[D1|DN]). 
objectHaveDomain(O,[D1|DN]).  % Subject and objects both have domains

canRead(S,O):-                % Subject can read object if the domain of the object is a subset of the domain of the subject.
    subjectHaveDomain(S,L1),
    objectHaveDomain(O,L2),
    subset(L2,L1).   

我尝试通过断言对象和主题来执行此操作,以找到使Subject为真的所有ObjectcanRead(Subject,Object),但我没有得到预期的结果。

1 ?- assert(subjectHavedomain(a,[s,p])).
true.

2 ?- assert(subjectHavedomain(b,[s,p,ts])).
true.

3 ?- assert(subjectHavedomain(c,[s])).
true.

4 ?- assert(objectHavedomain(o1,[s])).
true.

5 ?- assert(objectHavedomain(o2,[p,ts])).
true.

6 ?- assert(objectHavedomain(o3,[p])).
true.

7 ?- canRead(S,O).
true ;
true ;
true ;...

我期待:

S = a,
O = o1;
S = a,
O = o3;
S = b,
O = o1;
S = b,
O = o2;
S = b,
O = o3;
S = c,
O = o1;

提前致谢。

1 个答案:

答案 0 :(得分:0)

所以,为了将来的参考(鉴于这个问题在评论中得到了解决,但是我讨厌没有答案的问题),我们在这里有两个问题:

第一个问题基本上与here相同,变量用于导致问题的事实,由列表中的变量复合,允许无限递归。解决方法是删除:

subjectHaveDomain(S,[D1|DN]).
objectHaveDomain(O,[D1|DN]).

第二个问题是对动态谓词与断言的区分大小写。动态谓词为subjectHaveDomain/2objectHaveDomain/2,但您声明subjectHavedomain/2objectHavedomain/2,这是不同的事实。

最后,作为一个有点迂腐的说明,element/2谓词是member/2的重新实现,而subset/2谓词是subset/2的重新实现,如果你想使用内置函数而不是自己编写。