Prolog子列表关系
Prolog sublist Relation
我正在阅读 Ivan Bratko 的 Prolog Programming for Artificial Intelligence 一书,但我之前没有使用 Prolog 的经验。在书中,列表的子列表关系被表述为:
S is a sublist of L if:
1) L can be decomposed into two lists, L1 and L2, and
2) L2 can be decomposed into two lists, S and some L3.
关系如下:
sublist(S, L) :-
conc(L1, L2, L),
conc(S, L3, L2).
conc([], L, L).
conc([X|L1], L2, [X|L3]) :-
conc(L1, L2, L3).
我觉得很奇怪,为什么我们不将列表分解为两个列表并检查其中一个列表是否与 S 匹配?
这应该有帮助;关键 word/concept 是 difference list
.
来自 "Prolog Techniques",作者 Attila Csenki, Chapter 2 (Free PDF,带有嵌入式广告)
书后一点就是这张图
本书的第二部分实际上是一本单独的书,
"Applications of Prolog" Attila Csenki (Free PDF 嵌入广告)
为了比较,Logtalk库中使用的sublist/2
谓词的定义是:
sublist(List, List).
sublist(Sublist, [Head| Tail]) :-
sublist(Tail, Head, Sublist).
sublist(Sublist, _, Sublist).
sublist([Head| Tail], _, Sublist) :-
sublist(Tail, Head, Sublist).
sublist([Head| Tail], Element, [Element| Sublist]) :-
sublist(Tail, Head, Sublist).
IIRC,这是一个常见的 definition.Some 示例调用可能是:
?- list::sublist(Sublist, [1,2,3]).
Sublist = [1, 2, 3] ;
Sublist = [2, 3] ;
Sublist = [3] ;
Sublist = [] ;
Sublist = [2] ;
Sublist = [1, 3] ;
Sublist = [1] ;
Sublist = [1, 2].
?- list::sublist([1,2], List).
List = [1, 2] ;
List = [_1376, 1, 2] ;
List = [_1376, _1382, 1, 2] ;
List = [_1376, _1382, _1388, 1, 2] ;
...
?- list::sublist(Sublist, List).
Sublist = List ;
List = [_1172|Sublist] ;
List = [_1172, _1178|Sublist] ;
List = [_1172, _1178, _1184|Sublist] .
...
更新
注意到问题中的定义和我的答案中的定义不具有相同的语义。问题中的定义意味着连续的元素。例如
?- sublist(Sublist, [1,2,3]).
Sublist = [] ;
Sublist = [1] ;
Sublist = [1, 2] ;
Sublist = [1, 2, 3] ;
Sublist = [] ;
Sublist = [2] ;
Sublist = [2, 3] ;
Sublist = [] ;
Sublist = [3] ;
Sublist = [] ;
false.
此定义中的一个问题是多次生成空列表解决方案。
我觉得你写的时候很亲近:
It seems odd to me why we don't just decompose list into two lists and check whether one of the lists matches with S?
只需将列表 L
分解为 三个 个列表即可:
L1
是子列表("prefix")之前的列表,
S
是子列表本身,
L3
是子列表 ("suffix") 之后的列表。
由于 conc/3
只能连接(或分解)两个列表,而不是三个列表,因此需要 两个 conc/3
目标的结合。
conc(L1,L2,L), conc(S,L3,L2)
表示以上关系
我正在阅读 Ivan Bratko 的 Prolog Programming for Artificial Intelligence 一书,但我之前没有使用 Prolog 的经验。在书中,列表的子列表关系被表述为:
S is a sublist of L if:
1) L can be decomposed into two lists, L1 and L2, and
2) L2 can be decomposed into two lists, S and some L3.
关系如下:
sublist(S, L) :-
conc(L1, L2, L),
conc(S, L3, L2).
conc([], L, L).
conc([X|L1], L2, [X|L3]) :-
conc(L1, L2, L3).
我觉得很奇怪,为什么我们不将列表分解为两个列表并检查其中一个列表是否与 S 匹配?
这应该有帮助;关键 word/concept 是 difference list
.
来自 "Prolog Techniques",作者 Attila Csenki, Chapter 2 (Free PDF,带有嵌入式广告)
书后一点就是这张图
本书的第二部分实际上是一本单独的书,
"Applications of Prolog" Attila Csenki (Free PDF 嵌入广告)
为了比较,Logtalk库中使用的sublist/2
谓词的定义是:
sublist(List, List).
sublist(Sublist, [Head| Tail]) :-
sublist(Tail, Head, Sublist).
sublist(Sublist, _, Sublist).
sublist([Head| Tail], _, Sublist) :-
sublist(Tail, Head, Sublist).
sublist([Head| Tail], Element, [Element| Sublist]) :-
sublist(Tail, Head, Sublist).
IIRC,这是一个常见的 definition.Some 示例调用可能是:
?- list::sublist(Sublist, [1,2,3]).
Sublist = [1, 2, 3] ;
Sublist = [2, 3] ;
Sublist = [3] ;
Sublist = [] ;
Sublist = [2] ;
Sublist = [1, 3] ;
Sublist = [1] ;
Sublist = [1, 2].
?- list::sublist([1,2], List).
List = [1, 2] ;
List = [_1376, 1, 2] ;
List = [_1376, _1382, 1, 2] ;
List = [_1376, _1382, _1388, 1, 2] ;
...
?- list::sublist(Sublist, List).
Sublist = List ;
List = [_1172|Sublist] ;
List = [_1172, _1178|Sublist] ;
List = [_1172, _1178, _1184|Sublist] .
...
更新
注意到问题中的定义和我的答案中的定义不具有相同的语义。问题中的定义意味着连续的元素。例如
?- sublist(Sublist, [1,2,3]).
Sublist = [] ;
Sublist = [1] ;
Sublist = [1, 2] ;
Sublist = [1, 2, 3] ;
Sublist = [] ;
Sublist = [2] ;
Sublist = [2, 3] ;
Sublist = [] ;
Sublist = [3] ;
Sublist = [] ;
false.
此定义中的一个问题是多次生成空列表解决方案。
我觉得你写的时候很亲近:
It seems odd to me why we don't just decompose list into two lists and check whether one of the lists matches with S?
只需将列表 L
分解为 三个 个列表即可:
L1
是子列表("prefix")之前的列表,S
是子列表本身,L3
是子列表 ("suffix") 之后的列表。
由于 conc/3
只能连接(或分解)两个列表,而不是三个列表,因此需要 两个 conc/3
目标的结合。
conc(L1,L2,L), conc(S,L3,L2)
表示以上关系