List 如何在prolog中对列表列表执行算术运算

List 如何在prolog中对列表列表执行算术运算,list,prolog,List,Prolog,我正在编写一个函数,它接收列表中的一个元素,并将列表中的head元素与列表中的其他元素进行比较。我知道使用递归是如何在列表上执行大多数操作的,但我在尝试将其转换为列表时遇到了一些困难。这就是我到目前为止的想法: compareElements([H|T]) :- compareHeadList(H,T). compareHeadList([H|T],RestOfList) :- compare(T,H,GreaterList,LesserList), compareRe

我正在编写一个函数,它接收列表中的一个元素,并将列表中的head元素与列表中的其他元素进行比较。我知道使用递归是如何在列表上执行大多数操作的,但我在尝试将其转换为列表时遇到了一些困难。这就是我到目前为止的想法:

compareElements([H|T]) :-
    compareHeadList(H,T).

compareHeadList([H|T],RestOfList) :-
    compare(T,H,GreaterList,LesserList),
    compareRestList(RestOfList,H).

compareRestList(X,[HA|TA]) :-
    compare(HA,X,GreaterList,LesserList),
    compareRestList(X,TA).

compare([HA|TA],X,GreaterList,LesserList) :-
    X @> HA -> GreaterList = [HA|GreaterTail],
    compare(TA,X,GreaterTail,LesserList);
    LesserList = [HA|LesserTail],
    compare(TA,X,GreaterList,LesserTail).
compare([_|TA],X,GreaterList,LesserList) :-
    compare(TA,X,GreaterList,LesserList).
例如:

    compareElements(LoL).
    Where Lol = [[6,4,8],[7,9,2],[1,3,0]]
    My Goal is to compare 6 with every other element in the Lol, 
    so that GreaterList = [8,7,9], and LesserList = [4,2,1,3,0]
我对代码应该如何运行的想法是compareElements()接收列表,然后调用compareHeadList()将第一个列表的头与该列表中的其余元素进行比较。最后,compareRestList()应该接收要比较的Head元素和列表列表的其余部分,调用compare函数并返回true

我的问题是,当我写列表检查元素时,它输出的序列像“9c78”,它看起来像一个内存地址。我想知道我是否正确地比较了这些元素,并将它们正确地推到列表上,或者是否有另一部分导致了这种情况的发生

head_head([[X|_]|_], X).

split_list(_, [], [], []).
split_list(K, [H|T],     G, S) :- H = K, split_list(K, T, G, S).
split_list(K, [H|T], [H|G], S) :- H > K, split_list(K, T, G, S).
split_list(K, [H|T], G, [H|S]) :- H < K, split_list(K, T, G, S).

split_lol(X, G, S) :- head_head(X, K), append(X, L), split_list(K, L, G, S).

Prolog为您提供了一些kewl“向后”功能:

?- split_lol([[6,X,Y], [A, B]], [7, 8], [2, 1]).
X = 7,
Y = 8,
A = 2,
B = 1 ;
X = 7,
Y = 2,
A = 8,
B = 1 ;
X = 7,
Y = 2,
A = 1,
B = 8 ;
X = 2,
Y = 7,
A = 8,
B = 1 ;
X = 2,
Y = 7,
A = 1,
B = 8 ;
X = 2,
Y = 1,
A = 7,
B = 8 ;
false.

?- 

你的方法可以发挥作用。有关缺少的内容的提示,请参阅Prolog发出的以下警告:

Warning: /home/isabelle/lol.pl:4:
    Singleton variables: [GreaterList,LesserList]
Warning: /home/isabelle/lol.pl:8:
    Singleton variables: [GreaterList,LesserList]
单例变量警告严重。他们告诉你,你犯了一种打字错误,这通常会使一个程序变得毫无意义,或者(在本例中)你还没有将计算的某些部分与其他部分连接起来。在您的程序中,即使您计算其中一个嵌套列表的较大/较小列表,您也永远不会将其与其他嵌套列表的较大/较小列表相关联,因此您永远无法得到完整的答案

如果其中一个列表的较大列表是
[8]
,而另一个列表的较大列表是
[7,9]
,那么我们不知何故想要构建
[8,7,9]
的较大列表。Prolog中的一种常见方法是只计算部分列表:尾部不是
[]
而是变量的列表。在本例中,如果我们计算部分列表
[8 | Tail]
,然后要求下一次计算与
Tail
统一,我们将得到
[8,7,9 | Tail2]
的组合部分列表。将
Tail2
[]
相统一将最终关闭列表

下面是适应这种方法的代码,使用了更明确的名称:

list_element_greater_smaller([], _Y, GreaterTail, GreaterTail, SmallerTail, SmallerTail).
list_element_greater_smaller([X | Xs], Y, Greater, GreaterTail, Smaller, SmallerTail) :-
    (   X > Y
    ->  Greater = [X | Greater1],
        list_element_greater_smaller(Xs, Y, Greater1, GreaterTail, Smaller, SmallerTail)
    ;   Smaller = [X | Smaller1],
        list_element_greater_smaller(Xs, Y, Greater, GreaterTail, Smaller1, SmallerTail) ).

lists_element_greater_smaller([], _Y, GreaterTail, GreaterTail, SmallerTail, SmallerTail).
lists_element_greater_smaller([Xs | Xss], Y, Greater, GreaterTail, Smaller, SmallerTail) :-
    list_element_greater_smaller(Xs, Y, Greater, GreaterTail1, Smaller, SmallerTail1),
    lists_element_greater_smaller(Xss, Y, GreaterTail1, GreaterTail, SmallerTail1, SmallerTail).

lists_greater_smaller([[Y | Xs] | Xss], Greater, Smaller) :-
    lists_element_greater_smaller([Xs | Xss], Y, Greater, [], Smaller, []).
花点时间了解
尾部
变量是如何贯穿所有计算的,然后用
[]
结束的

其行为如下:

?- lists_greater_smaller([[6,4,8],[7,9,2],[1,3,0]], Greater, Smaller).
Greater = [8, 7, 9],
Smaller = [4, 2, 1, 3, 0].
只要列表的嵌套深度是固定的,还有一种更简单的方法来编写所有这些内容:您可以在嵌套列表上编写一个递归谓词,这与在“平面”列表上执行递归的方式非常类似。您将有三种情况需要区分:

  • 整个外部列表为空
  • 第一个嵌套列表为空
  • 第一个嵌套列表有一些头和尾
这种方法可以如下所示:

lists_greater_smaller2([[Y | Xs] | Xss], Greater, Smaller) :-
    lists_element_greater_smaller2([Xs | Xss], Y, Greater, Smaller).

lists_element_greater_smaller2([], _Y, [], []).
lists_element_greater_smaller2([[] | Xss], Y, Greater, Smaller) :-
    lists_element_greater_smaller2(Xss, Y, Greater, Smaller).
lists_element_greater_smaller2([[X | Xs] | Xss], Y, Greater, Smaller) :-
    (   X > Y
    ->  Greater = [X | Greater1],
        lists_element_greater_smaller2([Xs | Xss], Y, Greater1, Smaller)
    ;   Smaller = [X | Smaller1],
        lists_element_greater_smaller2([Xs | Xss], Y, Greater, Smaller1) ).
再说一遍:

?- lists_greater_smaller2([[6,4,8],[7,9,2],[1,3,0]], Greater, Smaller).
Greater = [8, 7, 9],
Smaller = [4, 2, 1, 3, 0] ;
false.

首先连接列表,然后对项目列表执行算术运算。是否可以使用append函数将列表连接到单个列表中@WillemVanOnsemyes,看一看。@JoshPokorny您希望输出为true,还是希望每个数字的大小都有一个列表?例如,对于6 GL=[1,2,3]LL=[18,39,40]。@ReemaQKhan我的目标是只输出true,但我正在使用列表和writeLn()来尝试测试我的函数,看看它们是否工作正常
?- lists_greater_smaller2([[6,4,8],[7,9,2],[1,3,0]], Greater, Smaller).
Greater = [8, 7, 9],
Smaller = [4, 2, 1, 3, 0] ;
false.