如何编写谓词来检查两个相同的 X 值是否有不同的 Y 值?

How to write predicate that checks whether for two same X values there are different Y values?

我正在尝试在 Prolog 中编写一个谓词,该谓词应该适用于如下一组事实:

value(a,b)
value(d,f)
value(p,k)

其中第一个值是X,第二个值是Y。并且它应该写出那些具有不同Y值的事实中是否有两个相同的X值。在上面的例子中谓词应该 return true 而在下面的例子中谓词应该 return false.

value(a,b)
value(d,f)
value(a,k)

我当前的谓词是这样的

have_different_Y_for_same_X :- relation(X, Y), not(relation(X, Z)).

无论值是否为真,我得到的所有结果都没有正常工作。

1- 首先在 checkX 中收集 XList 中的所有 X。

2- 在 checkX1 对于每个 X 收集它是 Y 在 YList 中。

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 值。它 returns 一个列表 (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
diff_2nds(X) :-
    value(X, Y1), value(X, Y2),
    Y1 \= Y2.

直接写出你的意思。 value/2 必须使用不同的值成功两次。
这给

?- diff_2nds(X).
X = a ;
X = a ;
false.

所以我对否定有疑问:如果没有这样的关系X和两个不同的[=12=,你希望它为真].下面的代码给出了想要的结果。

different_Y_for_same_X() :- 
    value(X, Y), 
    value(X, Z),
    Y @< Z.

no_different_Y_for_same_X() :- 
    \+ different_Y_for_same_X().