Prolog中未获取输入列表

Prolog中未获取输入列表,prolog,Prolog,我正在使用以下代码: item(a, b, c). item(a, a, c). item(a, d, c). item(a, c, b). main:- getItems(L), writeln('-----------1-------------'), writeln(L), findall((A,B,C), item(A,B,C), M), writeln('-----------2-------------'), compareItem(

我正在使用以下代码:

item(a, b, c).
item(a, a, c).
item(a, d, c).
item(a, c, b).

main:-
    getItems(L),
    writeln('-----------1-------------'),
    writeln(L),
    findall((A,B,C), item(A,B,C), M),
    writeln('-----------2-------------'),
    compareItem(M,L,I),
    writeln('-----------3-------------'),
    writeln(I).

getItems([Item|List]):-
    writeln('Enter:'),
    read(Item),
    dif(Item,stop),
    getItems(InputList).

getItems([]).

compareItem([H|T],L,Out):-
    writeln('-----------4-------------'),
    intersection(H,L,I),
    writeln('-----------5-------------'),
    compareItem(T,L,[I|Out]).
compareItem([],L,Out).
它给出以下输出:

?- main.
Enter:
|: a.
Enter:
|: b.
Enter:
|: stop.
-----------1-------------
[a|_G1003]
-----------2-------------
-----------4-------------
-----------1-------------
[a|_G1003]
-----------2-------------
-----------4-------------
-----------1-------------
[]
-----------2-------------
-----------4-------------
false.

4 ?-
输入法取自:

单独运行命令时,我会得到以下结果:

?- findall((A,B,C), item(A,B,C), M)
M = [ (a, b, c), (a, a, c), (a, d, c), (a, c, b)].
?- intersection([a,b,c],[a,b],I).
I = [a, b].
然而,它在M中是[(a,b,c),…],我希望用户输入是[a,b](这里是空白)

我希望输出是用户输入与M中每个项目的交集:

[(a,b), (a,a), (a), (a,b)]

同样,在达到第4点之后,执行如何再次达到第1点


如何纠正这些问题?谢谢

您只获得第一个元素,因为您从不使用包含其余元素的列表:

getItems([Item|List]):- writeln('Enter:'), read(Item), dif(Item,stop), getItems(InputList).
这意味着这两个变量在规则中只使用一次,因此可能是一个错误。

您只获得第一个元素,因为您从未使用包含其余元素的列表:

getItems([Item|List]):- writeln('Enter:'), read(Item), dif(Item,stop), getItems(InputList). 这意味着这两个变量在规则中只使用一次,因此可能是一个错误。

(a,b,c)
不是Prolog中的列表。这是一个表示规范形式的术语:
,(a),(b,c))
。列表
[A,b,c]
表示规范形式,
。(A),(b),。(c,[])
<代码>(a、b、c)不会像列表一样运行,因此不会给出您正在寻找的结果

如果要将收藏作为列表处理,请使用
findall([A,B,C],项(A,B,C),M)

关于原始谓词的另外两个问题已在上面解决:

  • 基本情况需要指出空列表
    []
    是与空列表匹配的结果。否则,
    Out
    永远不会被实例化
  • 您在递归中错误地放置了
    I
    变量,因为它需要是结果中第三个参数的头,而不是递归调用中的头
  • 实际上,您可以使用
    maplist
    执行此任务:

    compareItem(M, L, Out) :-
        maplist(intersection(L), M, Out).
    
    这将丢失您的
    writeln
    调用。如果愿意,您可以重新添加一个:

    intersect_with_writeln(A, B, R) :-
        writeln('-----------4-----------'),
        intersect(A, B, R).
    
    compareItem(M, L, Out) :-
        maplist(intersect_with_writeln(L), M, Out).
    
    (a,b,c)
    不是Prolog中的列表。这是一个表示规范形式的术语:
    ,(a),(b,c))
    。列表
    [A,b,c]
    表示规范形式,
    。(A),(b),。(c,[])
    <代码>(a、b、c)不会像列表一样运行,因此不会给出您正在寻找的结果

    如果要将收藏作为列表处理,请使用
    findall([A,B,C],项(A,B,C),M)

    关于原始谓词的另外两个问题已在上面解决:

  • 基本情况需要指出空列表
    []
    是与空列表匹配的结果。否则,
    Out
    永远不会被实例化
  • 您在递归中错误地放置了
    I
    变量,因为它需要是结果中第三个参数的头,而不是递归调用中的头
  • 实际上,您可以使用
    maplist
    执行此任务:

    compareItem(M, L, Out) :-
        maplist(intersection(L), M, Out).
    
    这将丢失您的
    writeln
    调用。如果愿意,您可以重新添加一个:

    intersect_with_writeln(A, B, R) :-
        writeln('-----------4-----------'),
        intersect(A, B, R).
    
    compareItem(M, L, Out) :-
        maplist(intersect_with_writeln(L), M, Out).
    

    谢谢输入部分现在正在工作,但仍然无法正确比较,因为M=[(a,b,c),(a,a,c),(a,d,c),(a,c,b)],并且输入是[a,b]。我如何将[a,b]与M的4个列表中的每一个进行比较?谢谢。输入部分现在正在工作,但仍然无法正确比较,因为M=[(a,b,c),(a,a,c),(a,d,c),(a,c,b)],并且输入是[a,b]。我如何将[a,b]与M的4个列表中的每一个进行比较?为什么在compareItem函数的递归调用中保留“[I | Out]”,而不是在其头中-pl也看到了这一点,在到达第4点后,执行如何再次到达第1点?实际上,compareItem([[a,b,c],[a,b,d],[c,b,d],[c,d],L](没有maplist)不起作用。我认为,您刚才复制了我自己的函数,现在我知道它是不正确的。@mso有几个项目我忽略了在您的原始谓词(不是函数)中修复我在回答中编辑的内容。在基本情况下,您需要有空列表
    []
    ,而不是
    Out
    。否则,
    Out
    永远不会被实例化。您的谓词也存在与joel67错误放置的变量相同的问题,我在编辑中也修复了该问题。为什么在compareItem函数的递归调用中保留“[I | Out]”而不是在其头中-pl请参见这一点,在达到点4后,执行如何再次达到点1?实际上,compareItem([[a,b,c],[a,b,d],[c,b,d],[c,d],L)(没有maplist)不起作用。我想,您只是复制了我自己的函数,现在我知道这是不正确的。@mso有几个项目我忽略了在您的原始谓词(不是函数)中修复我在回答中编辑的内容。在基本情况下,您需要有空列表
    []
    而不是
    Out
    。否则,
    Out
    永远不会被实例化。您的谓词也存在与joel67放置错误的变量相同的问题,我在编辑中也修复了该问题。