Prolog,带条件子句的建筑清单

时间:2011-05-16 21:34:01

标签: if-statement prolog conditional

我需要使用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)也不会发生,因为整个目标都会变错......

4 个答案:

答案 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(_).