Recursion Prolog中的递归问题-当退出递归时变为False而不是True

Recursion Prolog中的递归问题-当退出递归时变为False而不是True,recursion,prolog,Recursion,Prolog,我正试图用Prolog编写一个简单的程序来判断谓词是真是假。基本上我解决了这个问题,但我发现一个输入不起作用。我知道为什么,但我不知道如何解决它 谓词的形式如下: getPred(L, A, B, Y) L - is a list containing intv predicates - intv(K,L,V) - < K,L > is interval and V is any value < A,B > - is an interval Y - value 我

我正试图用Prolog编写一个简单的程序来判断谓词是真是假。基本上我解决了这个问题,但我发现一个输入不起作用。我知道为什么,但我不知道如何解决它

谓词的形式如下:

getPred(L, A, B, Y)

L - is a list containing intv predicates - intv(K,L,V) - < K,L > is interval and V is any value

< A,B > - is an interval

Y - value
我的代码是:

getPred(List, A, B, Y) :-
    S is 0,
    program(List, A, B, Y, S).

program([], _, _, Y, S) :-
    S =:= Y.

program([intv(K,L,V)|P], A, B, Y, S) :-
    isinINTV(K, L, V, A, B, P, Y, S).

isinINTV(K, L, V, A, B, P, Y, S) :-
    K >= A,
    L =< B,
    S2 = S+V,
    program(P,A,B,Y,S2).

isinINTV(K, L, V, A, B, P, Y, S) :-
    program(P,A,B,Y,S).
getPred(列表,A,B,Y):-
S是0,
程序(列表A、B、Y、S)。
程序([],[uu,[uu,Y,S):-
S=:=Y。
程序([intv(K,L,V)| P],A,B,Y,S):-
isinINTV(K,L,V,A,B,P,Y,S)。
isinINTV(K,L,V,A,B,P,Y,S):-
K>=A,
L=
除非我尝试这个谓词,否则我的程序运行得很好 getPred([intv(2,10,10),intv(5,8,10)],1,20,10)

问题是当Y!=S、 递归将返回并再次询问相同的条件,但稍后Y==S,因为在递归中返回意味着S中有一个旧值

谢谢你的帮助。
重要事项:我不想使用任何内置谓词。

试试:

check(Intervals, Inf, Sup, Value) :-
    check(Intervals, Inf, Sup, 0, Sum),
    Sum =:= Value.

check([], _, _, Sum, Sum).
check([intv(Inf0,Sup0,Value)| Intvs], Inf, Sup, Sum0, Sum) :-
    (   Inf0 >= Inf,
        Sup0 =< Sup ->
        Sum1 is Sum0 + Value,
        check(Intvs, Inf, Sup, Sum1, Sum)
    ;   check(Intvs, Inf, Sup, Sum0, Sum)
    ).

请注意,此解决方案还避免了原始代码中的虚假选择点。

S2=S+V
更改为
S2是S+V
。不要将术语统一(
=/2
)与算术求值(
is/2
)混淆。“重要的是:我不想使用任何内置谓词。”
=/2
=我知道。我指的是谓词,除了我已经使用过的谓词。我的意思是,我可以使用“关系运算符”。不管怎样,你能帮我解决这个问题吗?非常感谢!请你解释一下这行:checka([],u,u,Sum,Sum)。对我来说?我真的不确定如何将Sum传递到第一个谓词,以便比较Sum和value
check/5
谓词使用累加器从零开始计算Sum。当我们到达列表的末尾时(或者当输入列表为空时),累加器的值就是计算出的和的值。因此,我们简单地统一了最后两个论点。
getPred(List, A, B, Y) :-
    S is 0,
    program(List, A, B, Y, S).

program([], _, _, Y, S) :-
    S =:= Y.

program([intv(K,L,V)|P], A, B, Y, S) :-
    isinINTV(K, L, V, A, B, P, Y, S).

isinINTV(K, L, V, A, B, P, Y, S) :-
    K >= A,
    L =< B,
    S2 = S+V,
    program(P,A,B,Y,S2).

isinINTV(K, L, V, A, B, P, Y, S) :-
    program(P,A,B,Y,S).
check(Intervals, Inf, Sup, Value) :-
    check(Intervals, Inf, Sup, 0, Sum),
    Sum =:= Value.

check([], _, _, Sum, Sum).
check([intv(Inf0,Sup0,Value)| Intvs], Inf, Sup, Sum0, Sum) :-
    (   Inf0 >= Inf,
        Sup0 =< Sup ->
        Sum1 is Sum0 + Value,
        check(Intvs, Inf, Sup, Sum1, Sum)
    ;   check(Intvs, Inf, Sup, Sum0, Sum)
    ).
| ?- check([intv(2,10,15),intv(5,8,23), intv(12,15,8), intv(14,17,13)], 3, 16, 31).
yes

| ?- check([intv(2,10,15),intv(5,8,23), intv(12,15,8), intv(14,17,13)], 3, 20, 44).
yes

| ?- check([intv(2,10,10),intv(5,8,10)], 1, 20, 10).
no