2010-11-11 44 views
1

我几个星期前一直在研究Prolog,而我一直在困扰的一些小问题是使用append提出的解决方案。Prolog中的简单附加问题

举例来说,如果我有一个模式匹配规则,看起来像

pattern(foo(X,Y), L1, L) :- 
    % some code to go through a list (where the foo-pattern is) 
    % and add the pattern to the list L if it matches` 

我知道,追加/ 3是去这里的路,但..升未知开始即不接地,因为我们开始递归它开始填充匹配模式的列表。然而,我总是对最初发生的事情感到困惑,即当L不被磨光时。

例如,这里就是我们想要得到的所有匹配的模式列表时,第一个参数是可能的模式列表的码断位:

pat([foo(X,Y)|L1], R, L) :- 
    append(foo(X,Y),R,L), 
    pat(L1, R, [D|L]). 
pat([_|L1], R, L2) :- 
    pat(L1, R, L2). 

非常感谢。

回答

0

你可能会逃避一个不使用append/3的解决方案。例如,请考虑以下谓词,filter/3

filter(_Pattern, [], []). 
filter(Pattern, [E|Es], Matches) :- 
    Pattern \= E, !, 
    filter(Pattern, Es, Matches). 
filter(Pattern, [E|Es], [E|Matches]) :- 
    filter(Pattern, Es, Matches). 

filter/3的第一条是基本情况,其中,如果有什么(左)在第二个参数列表相匹配,那么我们就得到一个空列表。由于我们没有考虑Pattern,所以它被忽略(因此前面的_针对变量)。

filter/3试验的第二条款,以查看是否Pattern,这可能被绑定到一个术语(例如,foo(X,Y)),可以统一与列表的E第一元件相匹配。 \=运算符将会成功时,它的参数不能统一,所以如果这个成功,当我们不匹配E的模式,并可以扔掉它并继续(注意测试后切入!提交到这个分支)。

filter/3最后(第三)子句是在第二子句依赖的,因为它只是简单地传递E到假定它的匹配Pattern的最后一个参数列表Matches,因为前述条款未能确定它是不是一场比赛。请注意,我们将E附加到列表中,方法是将列表结构绑定到输出,使Matches子列表解除绑定;完整的Matches列表只有在达到基本情况后才会完全绑定,一旦我们用完第二个参数中的匹配条件,将其绑定到空列表[],创建类似[E1,E2,...,En|[]]的匹配模式;每个E1En匹配模式;这个词相当于名单[E1,E2,...,En]

测试这个谓词如下给出:

?- filter(foo(X,Y), [a,b,foo(x,y),c(f),foo(v(3),Z),5], L). 
L = [foo(x, y), foo(v(3), Z)] ; 
false. 

注意,一切unifiable与图案foo(X,Y)这里被过滤到必要L

最后一点:在你的代码中,append(foo(X,Y),R,L)总是会失败,因为append/3只对列表进行操作;您可能想拨打append([foo(X,Y)],R,L),但在这种情况下,您只需简单地使用L = [foo(X,Y)|R]作为简写。

编辑:要匹配,你有可能的模式列表匹配和筛选您的特定情况下,这里是另一个谓语,filter_list/3

filter_list(_Patterns, [], []). 
filter_list(Patterns, [E|Es], Matches) :- 
    filter(E, Patterns, []), !, 
    filter_list(Patterns, Es, Matches). 
filter_list(Patterns, [E|Es], [E|Matches]) :- 
    filter_list(Patterns, Es, Matches). 

注意filter_list/3依赖于我以前的定义并且使用完全相同的策略实施:如果EPatterns中的任何一个都不匹配(即,这是filter(E, Patterns, [])成功的情况),那么我们忘记E并继续,否则(最后一句)我们保留它。测试给了我们:

?- filter_list([foo(X,Y),bar(X),b], [a,b,foo(X,Y),c], L). 
L = [b, foo(X, Y)] ; 
false. 
0

我没有看父亲比...追加(富(...标准附加/ 3谓词名单工作的示例代码追加(FOO(。任何东西),...都不会匹配它的任何一个子句,因此你的第一个子句应该总是失败,第二个子句应该失败或者不能构造一个无限制的变量列表,当内存耗尽时最终会崩溃。你最终想在这里做什么,这对我来说并不是很清楚,但是这听起来像你不想在模式匹配中寻找与列表中的项目相匹配的项目,为什么你认为追加/ 3路要走吗?