繁体   English   中英

Prolog 谓词帮助:从列表中删除数字 N 次

[英]Prolog Predicate Help: Delete Number N times from List

问题: deleteNum(+Element, +List, -NewList, +NumToDelete)接受一个列表、一个元素以及要从List中删除的元素数。 NewList应该是原始List减去NumToDelete Elements 元素的哪些实例被删除并不重要,也不应给出替代答案。 例如,

例子:

?- deleteNum(3, [2,3,5,4,3,3], NewList, 2).
NewList = [2,5,4,3]

这是我尝试过的代码,但是当我尝试上面的示例时它一直返回 false。 我不确定为什么。

deleteNum(_, [],[], 0).
deleteNum(X, [X|T], T, 0).
deleteNum(X, [H|T], [H|T1], Num):- 
     Num1 is Num - 1, 
     deleteNum(X, T, T1, Num1).

非常感谢您提前。

您似乎将两种情况与此谓词混为一谈:

deleteNum(X, [H|T], [H|T1], Num):- 
     Num1 is Num - 1, 
     deleteNum(X, T, T1, Num1).

它没有删除X但它仍在减少Num

这里有几种方法可以做你想做的事:

deleteNum(_, L, L, 0).
deleteNum(X, [H|T], [H|T1], Num) :-
    X \= H,
    deleteNum(X, T, T1, Num).
    deleteNum(X, [X|T], T1, Num):- 
Num1 is Num - 1, 
    deleteNum(X, T, T1, Num1).

或者:

deleteNum(_, L, L, 0).
deleteNum(X, [X|T], T1, Num):- 
    !,
    Num1 is Num - 1, 
    deleteNum(X, T, T1, Num1).
deleteNum(X, [H|T], [H|T1], Num) :-
    deleteNum(X, T, T1, Num).

这要看你喜不喜欢! 或不。

两者都成功?- deleteNum(3, [2,3,5,4,3,3], NewList, 2), write(NewList), nl. 并将NewList统一为[2, 5, 4, 3]

请记住,Prolog 不会返回任何内容。 它只是成功或失败。 在此过程中,它只是试图统一变量以取得成功。

不是答案,而是不适合评论的调试帮助。

我们可以定义您的谓词必须满足的属性:

property(Element, List, NewList, Times) :-
    % first we call the predicate being tested ...
    deleteNum(Element, List, NewList, Times),
    % ... and then check the results
    findall(Element, between(1,Times,_), Elements),
    append(NewList, Elements, AllElements),
    msort(List, Sorted),
    msort(AllElements, Sorted).

即我们可以从ElementNewListTimes的原始列表中恢复所有元素。 此属性允许我们使用基于属性的测试来测试您的谓词。 使用 Logtalk 的lgtunit工具 QuickCheck 实现(您可以在大多数 Prolog 系统中运行)提供的基于属性的测试支持,我们得到:

?- {lgtunit(loader)}.
...

?- lgtunit::quick_check(property(+between(integer,1,10), +list(integer,1,10), -list(integer,1,10), +between(integer,1,10))).
*     quick check test failure (at test 1 after 0 shrinks):
*       property(1,[],A,1)
*     starting seed: seed(3172,9814,20125)
false.

失败会打印一个反例,您的谓词失败: property(1,[],A,1) ,即deleteNum(1,[],A,1) 您可以从修复这个简单的案例开始。 修复后,您可以再次运行lgtunit::quick_check/1查询以帮助定位更多错误(如果有剩余)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM