专柜,Prolog

时间:2012-02-08 23:32:56

标签: prolog counter

我想在两个列表(相同的长度)中计算相等且位于相同位置的元素数量。 例如: 假设我们有列表A = [3,6,7,9]和B = [2,6,4,9],我想在屏幕上打印消息,“找到2头公牛”。

到目前为止,我已经做到了这一点:

bulls([],[]).
bulls([Ha|Ta],[Hb|Tb]) :-
    Ha = Hb,
    writeln('bull found'),
    bulls(Ta,Tb);
    bulls(Ta,Tb).

每次在两个列表中存在于同一位置的元素时,都会打印出“bull found”消息。 在我看来,我想做出这样的事情:

bulls([],[],_).
bulls([Ha|Ta],[Hb|Tb],Counter) :-
    Ha = Hb,
    NewCounter is Counter + 1,
    bulls(Ta,Tb,NewCounter);
    bulls(Ta,Tb,NewCounter).

bulls(List1,List2):- bulls(List1,List2,0).

bulls从另一个规则中调用,该规则将列表传递给它。 如何制作它以便将“公牛”的值打印到屏幕上。有什么帮助吗?


修改 所以在 Suki的帖子之后,我让这个测试程序测试了2个列表:

bulls([],[],X), write(X), write('bulls found'),fail.
bulls([Ha|Ta],[Hb|Tb],Counter) :-
    Ha = Hb,
    NewCounter is Counter + 1,
    bulls(Ta,Tb,NewCounter);
    bulls(Ta,Tb,NewCounter).

check(List1,List2):- 
    bulls(List1,List2,0).


start:-
    A=[1,1,1,1],
    B=[2,1,2,1],
    writeln(A),writeln(B),
    check(A,B).

我得到了这个结果

1 ?- start.
[1,1,1,1]
[2,1,2,1]
ERROR: bulls/3: Arguments are not sufficiently instantiated

我做错了什么?

2 个答案:

答案 0 :(得分:1)

关于您编辑的节目:

第一个条款不是条款,这是一个目标!它应该是这样的:

bulls([],[],X) :- write(X), write(' bulls found').

你应该放弃fail,顺便说一句。

在第二个条款中,您需要使用“if-then-else”,并在“else”-branch中使用Counter代替NewCounter

bulls([Ha|Ta],[Hb|Tb],Counter) :-
  (
    Ha == Hb
  ->
    NewCounter is Counter + 1,
    bulls(Ta,Tb,NewCounter)
  ;
    bulls(Ta,Tb,Counter)
  ).

答案 1 :(得分:0)

假设你的prolog实现中存在谓词findall,length,nth0:
(以下内容来自swi-prolog)

A = [3,6,7,9], 
B = [2,6,4,9], 
findall(Y, ((nth0(X, A, Y), nth0(X, B, Y))), Y),
length(Y, LenY),
write(LenY), write(' Bulls Found').

[trace]  ?- A = [3,6,7,9], 
B = [2,6,4,9], 
findall(Y, ((nth0(X, A, Y), nth0(X, B, Y))), Y),
length(Y, LenY),
write(LenY), write(' Bulls Found').
   Call: (7) _G2814=[3, 6, 7, 9] ? creep
   Exit: (7) [3, 6, 7, 9]=[3, 6, 7, 9] ? creep
   Call: (7) _G2829=[2, 6, 4, 9] ? creep
   Exit: (7) [2, 6, 4, 9]=[2, 6, 4, 9] ? creep
^  Call: (7) findall(_G2834, (nth0(_G2832, [3, 6, 7, 9], _G2834), nth0(_G2832, [2, 6, 4, 9], _G2834)), _G2834) ? creep
   Call: (13) lists:nth0(_G2832, [3, 6, 7, 9], _G2834) ? creep
   Exit: (13) lists:nth0(0, [3, 6, 7, 9], 3) ? creep
   Call: (13) lists:nth0(0, [2, 6, 4, 9], 3) ? creep
   Fail: (13) lists:nth0(0, [2, 6, 4, 9], 3) ? creep
   Redo: (13) lists:nth0(_G2832, [3, 6, 7, 9], _G2834) ? creep
   Exit: (13) lists:nth0(1, [3, 6, 7, 9], 6) ? creep
   Call: (13) lists:nth0(1, [2, 6, 4, 9], 6) ? creep
   Exit: (13) lists:nth0(1, [2, 6, 4, 9], 6) ? creep
   Redo: (13) lists:nth0(_G2832, [3, 6, 7, 9], _G2834) ? creep
   Exit: (13) lists:nth0(2, [3, 6, 7, 9], 7) ? creep
   Call: (13) lists:nth0(2, [2, 6, 4, 9], 7) ? creep
   Fail: (13) lists:nth0(2, [2, 6, 4, 9], 7) ? creep
   Redo: (13) lists:nth0(_G2832, [3, 6, 7, 9], _G2834) ? creep
   Exit: (13) lists:nth0(3, [3, 6, 7, 9], 9) ? creep
   Call: (13) lists:nth0(3, [2, 6, 4, 9], 9) ? creep
   Exit: (13) lists:nth0(3, [2, 6, 4, 9], 9) ? creep
^  Exit: (7) findall([6, 9], user: (nth0(_G2832, [3, 6, 7, 9], [6, 9]), nth0(_G2832, [2, 6, 4, 9], [6, 9])), [6, 9]) ? creep
   Call: (7) length([6, 9], _G2848) ? creep
   Exit: (7) length([6, 9], 2) ? creep
   Call: (7) write(2) ? creep
2
   Exit: (7) write(2) ? creep
   Call: (7) write(' Bulls Found') ? creep
 Bulls Found
   Exit: (7) write(' Bulls Found') ? creep
A = [3, 6, 7, 9],
B = [2, 6, 4, 9],
Y = [6, 9],
LenY = 2.