为什么这个递归的Prolog谓词会在列表中增加一些"_1508 "一样的数字?

问题描述 投票:0回答:1

我的任务是将一个给定的排序列表拆分为 (LSorted) 变成其他几个,其中第一个将包含来自于 LSorted 小于第一个质数(1不被视为质数)的数。(来自Primes清单)第二条将包含来自LSorted的小于第二个质数但大于或等于第一个质数的值,等等。

ans(L, Res):-
    max_list(L, X),             /*determine the max value X of L*/
    listPrimes(X, Primes),      /*generate a list of primes up to X and the prime greater than X*/
    msort(L, LSorted),          /*sort L*/
    ans_recur(LSorted, Primes, Res),!.

ans_recur([], _, [[]|[]]).

ans_recur([InH|Input], [PrimeH|Primes], [[InH|Res]|ResT]):-
    InH < PrimeH,
    ans_recur(Input, [PrimeH|Primes], [Res|ResT]).

ans_recur([InH|Input], [_|Primes], [_|ResT]):-
    ans_recur([InH|Input], Primes, ResT).

当我运行一个查询。ans([1,2,3,4], L).,我得到的结果是:

L = [_1508, [1|_1522], [2|_1534], [3, 4]],而我期望 [[1], [2], [3,4]]. 该程序确实将数字 "放入""正确 "的列表中,但增加了一些值,如 _1508.据我了解,原因是Prolog试图给 Resans_recur 谓词,但它为什么要这样做呢?追踪。

Call:ans([1, 1, 2, 2, 3, 4], _13636)
 Call:lists:max_list([1, 1, 2, 2, 3, 4], _14050)
 Exit:lists:max_list([1, 1, 2, 2, 3, 4], 4)
 Call:listPrimes(4, _14080)
 Exit:listPrimes(4, [1, 2, 3, 5])
 Call:sort([1, 1, 2, 2, 3, 4], _14224)
 Exit:sort([1, 1, 2, 2, 3, 4], [1, 2, 3, 4])
 Call:ans_recur([1, 2, 3, 4], [1, 2, 3, 5], _13636)
 Call:1<1
 Fail:1<1
 Redo:ans_recur([1, 2, 3, 4], [1, 2, 3, 5], _13636)
 Call:ans_recur([1, 2, 3, 4], [2, 3, 5], _14156)
 Call:1<2
 Exit:1<2
 Call:ans_recur([2, 3, 4], [2, 3, 5], [_14174|_14168])
 Call:2<2
 Fail:2<2
 Redo:ans_recur([2, 3, 4], [2, 3, 5], [_14174|_14168])
 Call:ans_recur([2, 3, 4], [3, 5], _14168)
 Call:2<3
 Exit:2<3
 Call:ans_recur([3, 4], [3, 5], [_14204|_14198])
 Call:3<3
 Fail:3<3
 Redo:ans_recur([3, 4], [3, 5], [_14204|_14198])
 Call:ans_recur([3, 4], [5], _14198)
 Call:3<5
 Exit:3<5
 Call:ans_recur([4], [5], [_14234|_14228])
 Call:4<5
 Exit:4<5
 Call:ans_recur([], [5], [_14252|_14228])
 Exit:ans_recur([], [5], [[]])
 Exit:ans_recur([4], [5], [[4]])
 Exit:ans_recur([3, 4], [5], [[3, 4]])
 Exit:ans_recur([3, 4], [3, 5], [_14204, [3, 4]])
 Exit:ans_recur([2, 3, 4], [3, 5], [[2|_14204], [3, 4]])
 Exit:ans_recur([2, 3, 4], [2, 3, 5], [_14174, [2|_14204], [3, 4]])
 Exit:ans_recur([1, 2, 3, 4], [2, 3, 5], [[1|_14174], [2|_14204], [3, 4]])
 Exit:ans_recur([1, 2, 3, 4], [1, 2, 3, 5], [_14154, [1|_14174], [2|_14204], [3, 4]])
 Exit:ans([1, 1, 2, 2, 3, 4], [_14154, [1|_14174], [2|_14204], [3, 4]])
L = [_1282, [1|_1296], [2|_1308], [3, 4]]

先谢谢你.

prolog
1个回答
0
投票
ans_recur([InH|Input], [PrimeH|Primes], [[InH|Res]|ResT]):-
    InH < PrimeH,
    ans_recur(Input, [PrimeH|Primes], [Res|ResT]).

ans_recur([InH|Input], [_|Primes], [_|ResT]):-
    ans_recur([InH|Input], Primes, ResT).

你在这些子句中想表达的是这样的。

  • 如果 InH 小于下一个质数,它应该是当前运行结果的一部分。
  • 否则,它应该是以后运行结果的一部分。

但在最后一种情况下,"当前运行结果 "已经结束,它没有了元素。所以它的尾部,到目前为止是开放的,必须关闭。你需要相应地改变最后一个子句的头部。

ans_recur([InH|Input], [_|Primes], [[]|ResT]):-

现在它的行为是这样的

?- ans_recur([1,2,3,4,5,6,7,8,9,10], [2,3,5,7,11], Result).
Result = [[1], [2], [3, 4], [5, 6], [7, 8, 9, 10]] ;
Result = [[1], [2], [3, 4], [5], [6, 7, 8, 9|...]] ;
Result = [[1], [2], [3, 4], [], [5, 6, 7, 8|...]] ;
Result = [[1], [2], [3], [4, 5, 6], [7, 8, 9, 10]] .  % further incorrect answers

问题是你没有明确地表达 "否则 "的条件 Prolog不会隐含地猜测到这是你的意思 你可以把最后一个子句改成这样。

ans_recur([InH|Input], [PrimeH|Primes], [[]|ResT]):-
    InH >= PrimeH,
    ans_recur([InH|Input], Primes, ResT).

只得到预期的答案

?- ans_recur([1,2,3,4,5,6,7,8,9,10], [2,3,5,7,11], Result).
Result = [[1], [2], [3, 4], [5, 6], [7, 8, 9, 10]] ;
false.

正如你所看到的,我只处理了你的实现... ans_recur/3. 可能还有更多的错误残留在代码的其余部分。我们无法判断,因为你发布的代码不完整。今后,请只发布完整的程序。许多贡献者不会费心去尝试为你完成你的问题,你会得到更少的答案。

© www.soinside.com 2019 - 2024. All rights reserved.