【问题标题】:Prolog - matching similar pattern using variableProlog - 使用变量匹配相似的模式
【发布时间】:2014-10-07 03:05:20
【问题描述】:

我有一个通过调用list1(a,X) 定义为list1(a,[_,a,_]). 的模式,它会给出:

X = [_G3801, a, _G3807].

我需要写一个谓词match(X, List_in, List_out),这样通过调用它 Listin = [[b,a,b],[b,b,a],[a,a,a],[c,c,b]],它可以给出所有匹配的模式。像这样的:

list1(a,X),match(X,[[b,a,b],[b,b,a],[a,a,a],[c,c,b]], List_out).

那么它可以给出:

List_out = [[b,a,b],[a,a,a]].

我试过list1(a,X),include(member(X),[[b,a,b],[b,b,a],[a,a,a],[c,c,b]],Y). 它给出了

X = [_G4381, a, _G4387],
Y = [].

这不是我需要的。 谓词应该能够泛化,因为 list1(a,X) 可以任意定义, 例如给list2(a,[_,_,_]),然后

list2(a,X),match(X,[[b,a,b],[b,b,a],[a,a,a],[c,c,b]], List_out).

应该给

List_out =[[b,a,b],[b,b,a],[a,a,a],[c,c,b]].

X 必须是变量列表,因为它实际上是程序其他部分的结果,我只是使用list1(a,X) 来演示问题)。

棘手的部分是我不能逐个元素检查,X 只会与第一个匹配项统一,而错过所有其他匹配项。这更像是打电话:

list1(a,X),member(X,[[b,a,b],[b,b,a],[a,a,a],[c,c,b]]).
X = [b, a, b] ;
X = [a, a, a] ;
false.

找到第一个匹配后,只能回溯寻找第二个。 但是如何将所有回溯结果放入一个输出列表中?有人可以帮帮我吗?

【问题讨论】:

  • 你试过使用bagof谓词吗?
  • 谢谢,这正是我要找的!

标签: list variables prolog pattern-matching


【解决方案1】:

看来你做的比预期的要复杂:

list1(E, [_,E,_]).
pred1(X) :- list1(a,X),member(X,[[b,a,b],[b,b,a],[a,a,a],[c,c,b]]).

会给

?- pred1(X).
X = [b, a, b] ;
X = [a, a, a] ;

然后您可以将查询包装在 findall/3 中。 '服务谓词' list1/2 没用,用 (=)/2 (即统一)- 代替:

pred1(X) :- X=[_,a,_],member(X,[[b,a,b],[b,b,a],[a,a,a],[c,c,b]]).

Prolog 仍然能够让我感到惊讶(特别是 include/3)。我尝试了(部分)你的代码

?- include(member(X),[[b,a,b],[b,b,a],[a,a,a],[c,c,b]],Y).
X = b,
Y = [[b, a, b], [b, b, a], [c, c, b]].

不错!

【讨论】:

  • 'findall' 和 'bagof' 在我的情况下都很有用,“bagof” 可能更合适。 'list1/2' 只是为了让我提出问题。正如我所提到的,X 的模式是任意的,并且是程序其他部分的结果,因此无法在谓词中定义修复模式。但无论如何,感谢您的宝贵建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
  • 1970-01-01
  • 2022-11-30
  • 2013-08-15
相关资源
最近更新 更多