代码之家  ›  专栏  ›  技术社区  ›  Ellis Thompson

Prolog坐标检查

  •  0
  • Ellis Thompson  · 技术社区  · 6 年前

    我试图查看列表,如果指定值在给定行中出现两次,则返回true。例如

    %B is a list of lists such the positions of x are denoted by the values
    [[1,1],[2,3],[3,2]] would be visualized like:
    x--
    --x
    -x-
    

    这些坐标用b表示 所以方法foo(b),其中b=

    [[1,1],[1,3],[2,3],[3,3]] = true
    

    因为X会在第一行出现两次。

    1 回复  |  直到 6 年前
        1
  •  0
  •   damianodamiano    6 年前

    如注释部分所述,您需要检查列表中的两对是否具有相同的X坐标。因此,首先想到的解决方案可能是这样的(添加了一些writeln来破坏价值观):

    solution1(L):-
        member([X,Y1],L),
        member([X,Y2],L),    
        writeln([X,Y1]),
        writeln([X,Y2]).
    

    预设的 member/2 检查作为第二个参数传递的列表中是否存在第一个元素。运行查询 ?- solution1([[1,1],[1,3],[2,3],[3,3]]). 我们得到以下结果:

    ?- solution1([[1,1],[1,3],[2,3],[3,3]]).
    
    [1, 1]
    [1, 1]
    true
    [1, 1]
    [1, 3]
    true
    [1, 3]
    [1, 1]
    true
    [1, 3]
    [1, 3]
    true
    [2, 3]
    [2, 3]
    true
    [3, 3]
    [3, 3]
    true
    

    嗯,很多解决方案,不是我们想要的。问题之一是,用这种方式写, 成员/ 2 检查整个列表,以便在每种情况下都获得解决方案,因为通过第一个调用选择的每对 memeber/2 在列表中。用第二 成员/ 2 我们可以选择相同的元素,这样谓词就成功了。 为了避免这种行为,我们可以编写如下谓词:

    solution2([[A,_]|T]):-
        member([A,_],T).
    solution2([[_,_]|T]):-
        solution2(T).
    

    使用第二个谓词,我们检查所选元素是否存在于列表的其余部分中,因此我们从搜索中排除元素本身,只得到一个解决方案。

    ?- solution2([[1,1],[1,3],[2,3],[3,3]]).
    true
    false
    

    注意,这是一个非常简单的实现,也许有更好的方法来解决这个问题。