Prolog - 退出递归给出错误的值

时间:2017-11-26 19:32:25

标签: recursion prolog

所以我做了这个代码来找到两个列表之间的交集。

intersect([], _, C).
intersect([A1|AS], B, C) :-
    member(A1, B), length(C, L), L =:= 0, intersect(AS, B, [A1]);
    member(A1, B), length(C, L), L =\= 0, append(C, [A1], D), intersect(AS, B, D);
    intersect(AS, B, C).

当列表A为空时,它确实找到了交叉点,但是C的值将是一个空列表。 在此命令上使用trace “intersect([1,2,3,4,5,6,7,8],[4,5,6],C)。”我得到了这个:< / p>

    > Call: (16) intersect([], [4, 5, 6], [4, 5, 6]) ? creep    Exit: (16) 
    > intersect([], [4, 5, 6], [4, 5, 6]) ? creep    Exit: (15)
    > intersect([8], [4, 5, 6], [4, 5, 6]) ? creep    Exit: (14)
    > intersect([7, 8], [4, 5, 6], [4, 5, 6]) ? creep    Exit: (13)
    > intersect([6, 7, 8], [4, 5, 6], [4, 5]) ? creep    Exit: (12)
    > intersect([5, 6, 7, 8], [4, 5, 6], [4]) ? creep    Exit: (11)
    > intersect([4, 5, 6, 7, 8], [4, 5, 6], []) ? creep    Exit: (10)
    > intersect([3, 4, 5, 6, 7, 8], [4, 5, 6], []) ? creep    Exit: (9)
    > intersect([2, 3, 4, 5, 6, 7, 8], [4, 5, 6], []) ? creep    Exit: (8)
    > intersect([1, 2, 3, 4, 5, 6, 7, 8], [4, 5, 6], []) ? creep

请注意在调用时如何找到C的值并且它是正确的。然而,当它退出递归时它只是恢复到原始值,我该如何解决这个问题呢? (如果我在基本情况下添加write(C),它将打印正确的值。)

1 个答案:

答案 0 :(得分:5)

通过添加 false 目标,您的计划是专业化

intersect([], _, C).
intersect([A1|AS], B, C) :-
   (  false, member(A1, B), length(C, L), L =:= 0,
      intersect(AS, B, [A1])
   ;  false, member(A1, B), length(C, L), L =\= 0,
      append(C, [A1], D),
      intersect(AS, B, D)
   ;  intersect(AS, B, C)
   ).

添加 false 已删除某些解决方案。然而,剩下的是最后的替代方案,它始终适用。你需要解决这个问题。

而不是length(C, L), L =:= 0代替C = []代替length(C, L), L =\= 0代替C = [_|_]