我正在尝试在 Prolog 中编写一个谓词,该谓词应该适用于以下一组事实:
value(a,b)
value(d,f)
value(p,k)
其中第一个值是X,第二个是Y。并且应该写在那些具有不同Y值的事实中是否有两个相同的X值。在上面的例子中,谓词应该返回 true,在下面的例子中,谓词应该返回 false。
value(a,b)
value(d,f)
value(a,k)
我当前的谓词是这个
have_different_Y_for_same_X :- relation(X, Y), not(relation(X, Z)).
无论值是否为真,我都会得到所有结果,因此它无法正常工作。
答案 0 :(得分:0)
1- 首先在 checkX
中收集 XList 中的所有 X。
2- 在 checkX1
中,对于每个 X 收集它在 YList 中的 Y。
3- 最后在 checkX2
中,对于每个 X,使用 same
谓词检查它的 Y 是否相同。
value(a,b).
value(d,f).
value(a,k).
checkX:-
findall(X1,value(X1,_),XList),
checkX1(XList,YList),
checkX2(XList,YList).
checkX1([],[]).
checkX1([H|T],[YList|List]):-
findall(Y,value(H,Y),YList),
checkX1(T,List).
checkX2([],[]).
checkX2([H|T],[H2|T2]):-
(
\+same(H2)->
write('X='),
write(H),
write(' '),
write('Y='),
writeln(H2),
writeln('true'),
checkX2(T,T2);
write('X='),
write(H),
write(' '),
write('Y='),
writeln(H2),
writeln('false'),
checkX2(T,T2)).
same([]). % You only need this one if you want the empty list to succeed
same([_]).
same([X,X|T]) :- same([X|T]).
示例:
?-checkX
X=a Y=[b, k]
true
X=d Y=[f]
false
X=a Y=[b, k]
true
1true
这是我的方法:
1- 定义事实。
2- checkX
谓词使用 findall
查找 X 的所有 Y 值。它返回一个列表 (YList=[b,k])
。
3- 然后检查列表中的元素是否不相同,使用 (\+)
表示不相同。
value(a,b).
value(d,f).
value(a,k).
checkX(X):-
findall(Y,value(X,Y),YList),
\+same(YList).
same([]). % You only need this one if you want the empty list to succeed
same([_]).
same([X,X|T]) :- same([X|T]).
示例:
?-checkX(a).
1true
现在假设我有以下事实:
value(a,k).
value(d,f).
value(a,k).
?-checkX(a).
false
答案 1 :(得分:0)
diff_2nds(X) :-
value(X, Y1), value(X, Y2),
Y1 \= Y2.
直接写出你的意思。 value/2
必须使用不同的值成功两次。
这给
?- diff_2nds(X).
X = a ;
X = a ;
false.
答案 2 :(得分:0)
所以我对否定有一个问题:如果X
和两个不同的Y
没有这样的关系,你希望它为真。以下代码给出了所需的结果。
different_Y_for_same_X() :-
value(X, Y),
value(X, Z),
Y @< Z.
no_different_Y_for_same_X() :-
\+ different_Y_for_same_X().