Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog中的简单附加问题_Prolog - Fatal编程技术网

Prolog中的简单附加问题

Prolog中的简单附加问题,prolog,Prolog,几周前,我一直在学习Prolog,而我一直坚持的一件小事就是使用append提出解决方案 例如,如果我有一个模式匹配规则 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` 我知道append/3是这里的方式,但是。。L开始未知,即不接地,当我们开始递

几周前,我一直在学习Prolog,而我一直坚持的一件小事就是使用append提出解决方案

例如,如果我有一个模式匹配规则

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`
我知道append/3是这里的方式,但是。。L开始未知,即不接地,当我们开始递归列表时,它开始填充匹配的模式。然而,我总是对最初发生的事情感到困惑,即当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).

非常感谢。

您可能会得到一个不使用
append/3
的解决方案。例如,考虑下面的谓词,<代码>过滤器/ 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_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/3
的第一个子句是基本情况,如果第二个参数列表中没有(左)匹配项,那么我们将得到一个空列表。因为我们没有考虑<代码>模式< /代码>,所以忽略了它(因此前面的<代码> < /代码>对变量)。
filter/3
的第二个子句测试
Pattern
,它可以绑定到一个术语(例如
foo(X,Y)
),是否可以与列表中要匹配的第一个元素
e
相统一。
\=
运算符将在其参数无法统一时成功,因此如果成功,当我们没有将
E
与模式匹配时,可以将其丢弃并继续(请注意,在测试后剪切
以提交到此分支)

filter/3
的最后一个(第三个)子句依赖于第二个子句,因为它只是将
E
传递到最后一个参数列表
Matches
,假设它与
模式
匹配,因为前面的子句无法确定它不匹配。请注意,我们通过将列表结构绑定到输出,将
匹配项保持为未绑定状态,从而将
E
附加到列表中;完整的
匹配
列表只有在到达基本大小写时才会被完全绑定,一旦在第二个参数中匹配的术语用完,就会将其绑定到空列表
[]
,创建类似
[E1,E2,…,En |[]
,其中每个
E1
En
匹配模式;该术语相当于列表
[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.
请注意,这里所有与模式
foo(X,Y)
相统一的内容都会根据需要过滤到
L

最后一点注意:在您的代码中,调用
append(foo(X,Y),R,L)
将始终失败,因为
append/3
仅对列表进行操作;您可能想调用
append([foo(X,Y)],R,L)
,但在这种情况下,您只需将
L=[foo(X,Y)| R]
用作速记

编辑:要匹配您的特定情况,即您有可能匹配和筛选的模式列表,这里有另一个谓词,
filter\u list/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_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\u list/3
取决于我之前对
filter/3
的定义,并且是使用完全相同的策略实现的:如果
E
与任何
模式
不匹配(即,这是
筛选(E,Patterns,[])
成功的情况),那么我们将忘记
E
,然后继续,否则(最后一条)我们保留它。测试为我们提供:

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

在您的示例代码中,除了…append(foo)(…标准的append/3谓词对list.append(foo(任何内容))进行操作外,我不必看父亲,…与它的任何一个子句都不匹配。因此,您的第一个示例子句应该始终失败,第二个示例子句应该失败或开始构建无限多的未绑定变量列表,最终在内存耗尽时崩溃。至于您最终想在这里做什么,我现在还不清楚,但听起来您似乎不想这样做模式匹配,甚至在列表中查找与给定术语统一的项。为什么您认为append/3是一种方法