我需要使用prolog(SWI-flavor)完成这项作业,并且无法理解某些事情。
例如,如果我想遍历列表并将其元素添加到另一个列表中,但只有当它们满足某些条件时,我该如何处理它?我可以将它们全部添加,或者不添加,但如果我添加检查此条件的子句,则整个递归结果为“false”。我理解为什么会这样,但不知道如何解决它。基本上我想要的是:
goal(Stuff) :- do_something(X),
only_do_this_if_something(Y),
always_do_this(Z).
目前,如果only_do_this_if_something(Y)
失败,那么always_do_this(Z)
也不会发生,因为整个目标都会变错......
答案 0 :(得分:10)
你可以使用if结构:
<condition> -> (do_something) ; (do_something else)
在这种情况下:
goal(Stuff):-
do_something(X),
if_something(Y)-> do_this(Y) ; true,
always_do_this(Z).
或者您只需编写两个子句,如:
goal(Stuff):-
do_something(X),
conditional_stuff(Y),
always_do_this(Z).
conditional_stuff(Y):-
condition(Y),
do_this(Y).
conditional_stuff(_).
答案 1 :(得分:1)
检查以下编程模式,在Prolog中使用了很多:
您必须使用剪切(!)禁止回溯或明确检查条件不适用于后一条款。
请注意,您说您想要一个输出列表,其中包含应用了“某些内容”的项目(这不是您在代码中编写的内容)...
将此模式应用于您的问题,它看起来像这样:
myRecursion([], []). % This is the base case
myRecursion([Item|Tail], [Item|NTail]):-
something_applies(...),
do_something(...),
only_do_this_if_something(...),
always_do_this(...).
myRecursion(Tail, NTail).
myRecursion([Item|Tail], NTail):-
not(something_applies(...)),
do_something(...),
always_do_this(...),
myRecursion(Tail, NTail).
答案 2 :(得分:1)
如果我理解正确,那么您需要的是一个谓词include/3
:
include(:Goal, +List1, ?List2)
Filter elements for which Goal succeeds. True if List2 contains
those elements Xi of List1 for which call(Goal, Xi) succeeds.
用法示例:
?- include(number, [a(b), 2, _, 1.2, C, '1'], L).
L = [2, 1.2].
现在你的作业变成了“如何实施include/3
”。实施include/3
版本后,您可以查看其源代码listing(include)
来检查它是否符合SWI的版本。
答案 3 :(得分:0)
尝试ignore / 1谓词:
goal(Stuff) :-
do_something(X)
ignore(only_do_this_if_something(Y)),
always_do_this(Z).
ignore / 1调用唯一的参数并在失败时成功:
ignore(X) :- X, !.
ignore(_).