【问题标题】:How to write predicate that checks whether for two same X values there are different Y values?如何编写谓词来检查两个相同的 X 值是否有不同的 Y 值?
【发布时间】:2021-01-16 10:28:58
【问题描述】:

我正在尝试在 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)

我当前的谓词是this

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

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

【问题讨论】:

    标签: prolog


    【解决方案1】:

    所以我对否定有疑问:如果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().
    

    【讨论】:

      【解决方案2】:
      diff_2nds(X) :-
          value(X, Y1), value(X, Y2),
          Y1 \= Y2.
      

      只要准确地写出你的意思。 value/2 必须使用不同的值成功两次。
      这给了

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

      【讨论】:

        【解决方案3】:

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

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

        3- 最后在checkX2 中,使用same 谓词检查每个X 的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
        

        【讨论】:

        • 这个解决方案很棒,但是,我想创建一个谓词,对所有 X 执行此操作,并查找任何两个相同的 X 是否存在不同的 Y 值,而无需输入 X 参数。
        猜你喜欢
        • 2023-03-22
        • 1970-01-01
        • 2014-02-03
        • 1970-01-01
        • 2015-01-25
        • 1970-01-01
        • 2017-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多