Prolog 将列表拆分为单独的列表
我必须为我的列表定义更多的约束 我想将我的列表拆分为单独的列表 例如:Prolog 将列表拆分为单独的列表,prolog,logical-purity,Prolog,Logical Purity,我必须为我的列表定义更多的约束 我想将我的列表拆分为单独的列表 例如: List=[[1,1],[_,0],[_,0],[_,0],[3,1],[_,0],[9,1],[2,0],[4,0]] 我需要从主列表中获得三个列表: [[_,0],[_,0],[_,0]] and [[_,0]] and [[2,0],[4,0]] 所以我总是需要一组列表,在一个带有[X,1]的术语之间 如果你能给我小费就太好了。不需要解决方案,只需要一个提示如何解决这个问题 Jörg您可以使用类似于append/3
List=[[1,1],[_,0],[_,0],[_,0],[3,1],[_,0],[9,1],[2,0],[4,0]]
我需要从主列表中获得三个列表:
[[_,0],[_,0],[_,0]] and [[_,0]] and [[2,0],[4,0]]
所以我总是需要一组列表,在一个带有[X,1]的术语之间
如果你能给我小费就太好了。不需要解决方案,只需要一个提示如何解决这个问题
Jörg您可以使用类似于
append/3
的谓词。例如,要在第一次出现atomx
时拆分列表,您可以说:
?- L = [a,b,c,d,x,e,f,g,x,h,i,j], once(append(Before, [x|After], L)).
L = [a, b, c, d, x, e, f, g, x|...],
Before = [a, b, c, d],
After = [e, f, g, x, h, i, j].
正如@false所指出的,添加一个额外的需求可能会改变结果,但这就是使用append/3
的好处:
“在x
上拆分列表,以便第二部分以h
开头:
?- L = [a,b,c,d,x,e,f,g,x,h,i,j], After = [h|_], append(Before, [x|After], L).
L = [a, b, c, d, x, e, f, g, x|...],
After = [h, i, j],
Before = [a, b, c, d, x, e, f, g].
这只是提示。您可以使用类似于
append/3
的谓词。例如,要在其中第一次出现atomx
时拆分列表,您可以说:
?- L = [a,b,c,d,x,e,f,g,x,h,i,j], once(append(Before, [x|After], L)).
L = [a, b, c, d, x, e, f, g, x|...],
Before = [a, b, c, d],
After = [e, f, g, x, h, i, j].
正如@false所指出的,添加一个额外的需求可能会改变结果,但这就是使用append/3
的好处:
“在x
上拆分列表,以便第二部分以h
开头:
?- L = [a,b,c,d,x,e,f,g,x,h,i,j], After = [h|_], append(Before, [x|After], L).
L = [a, b, c, d, x, e, f, g, x|...],
After = [h, i, j],
Before = [a, b, c, d, x, e, f, g].
这只是提示。不清楚“一组列表”是什么意思。在您的示例中,您从符合
[[1,1]
标准的[1,1]
开始。那么,一开始不应该有一个空的列表吗?或者你是说一切都是从这样一个标记开始的?
如果周围还有更多的标记呢
首先,需要定义标记元素的标准。这两种情况都适用:适用和不适用,因此这是介于两者之间的元素
marker([_,1]).
nonmarker([_,C]) :-
dif(1, C).
注意,使用这些谓词,我们意味着每个元素都必须是[[uu,.]
。你没有说,但这是有道理的
split(Xs, As, Bs, Cs) :-
phrase(three_seqs(As, Bs, Cs), Xs).
marker -->
[E],
{marker(E)}.
three_seqs(As, Bs, Cs) -->
marker,
all_seq(nonmarker, As),
marker,
all_seq(nonmarker, Bs),
marker,
all_seq(nonmarker, Cs).
有关all_seq//2
的定义,请参见
人们可以用
all_seq(marker,[[u])代替marker
,不清楚“列表组”是什么意思。在您的示例中,您从符合[[1,1]
标准的[1,1]
开始。那么,一开始不应该有一个空的列表吗?或者你是说一切都是从这样一个标记开始的?
如果周围还有更多的标记呢
首先,需要定义标记元素的标准。这两种情况都适用:适用和不适用,因此这是介于两者之间的元素
marker([_,1]).
nonmarker([_,C]) :-
dif(1, C).
注意,使用这些谓词,我们意味着每个元素都必须是[[uu,.]
。你没有说,但这是有道理的
split(Xs, As, Bs, Cs) :-
phrase(three_seqs(As, Bs, Cs), Xs).
marker -->
[E],
{marker(E)}.
three_seqs(As, Bs, Cs) -->
marker,
all_seq(nonmarker, As),
marker,
all_seq(nonmarker, Bs),
marker,
all_seq(nonmarker, Cs).
有关all_seq//2
的定义,请参见
代替marker
,可以编写all_seq(marker,[[u])
此实现尝试保留列表项,而不限制列表项为[[uu,][/code>,如
做
我可以看出,实施上述限制确实很有意义。。。不过,我还是想把它提出来,谈谈更普遍的问题
以下内容基于并具体化了谓词,marker\u truth/2
。
marker\u真值(M,T)
将M
的“标记”属性具体化为真值T
(true
或false
)
哦强>
上面显示的第二个答案肯定不是我们想要的。
显然,splitlistIf/3
此时应该有splitLs
,
因为目标是_标记([9,1])
成功了。没有。相反,我们得到的答案是一个冻结的dif/2
目标,这个目标永远不会被唤醒,因为它正在等待匿名变量\u E
的实例化
猜猜谁该受责备!marker\u truth/2
的第二句:
marker_truth(Xs,false) :- dif(Xs,[_,1]). % BAD
?- marker_truth(M,Truth). % most general use
Truth = true, M = [_A,1] ;
Truth = false, freeze(M, nonMarker__1(M)).
所有这些代码,用于表示的安全逻辑否定是\u标记([\u1])
?丑
让我们看看它(至少)是否有助于上述问题(给出如此多无用答案的问题)
这不是我们想要的答案。为了了解原因,让我们看看以下类似用法的答案:
在最一般的情况下,有两个答案--这就是具体化谓词的行为方式
让我们相应地重新编码marker\u truth/2
:
marker_truth(Xs,Truth) :- subsumes_term([_,1],Xs), !, Truth = true.
marker_truth(Xs,Truth) :- Xs \= [_,1], !, Truth = false.
marker_truth([_,1],true).
marker_truth(Xs ,false) :- nonMarker__1(Xs).
nonMarker__1(T) :- var(T), !, freeze(T,nonMarker__1(T)).
nonMarker__1(T) :- T = [_|Arg], !, nonMarker__2(Arg).
nonMarker__1(_).
nonMarker__2(T) :- var(T), !, freeze(T,nonMarker__2(T)).
nonMarker__2(T) :- T = [_|_], !, dif(T,[1]).
nonMarker__2(_).
让我们使用新的marker\u truth/2实现重新运行上述查询:
marker_truth(Xs,false) :- dif(Xs,[_,1]). % BAD
?- marker_truth(M,Truth). % most general use
Truth = true, M = [_A,1] ;
Truth = false, freeze(M, nonMarker__1(M)).
此实现尝试保留列表项,但不将列表项限制为[\u,\u]
,如
做
我可以看出,实施上述限制确实很有意义。。。不过,我还是想把它提出来,谈谈更普遍的问题
以下内容基于并具体化了谓词,marker\u truth/2
。
marker\u真值(M,T)
将M
的“标记”属性具体化为真值T
(true
或false
)
哦强>
上面显示的第二个答案肯定不是我们想要的。
显然,splitlistIf/3
此时应该有splitLs
,
因为目标是_标记([9,1])
成功了。没有。相反,我们得到的答案是一个冻结的dif/2
目标,这个目标永远不会被唤醒,因为它正在等待匿名变量\u E
的实例化
猜猜谁该受责备!marker\u truth/2
的第二句:
marker_truth(Xs,false) :- dif(Xs,[_,1]). % BAD
?- marker_truth(M,Truth). % most general use
Truth = true, M = [_A,1] ;
Truth = false, freeze(M, nonMarker__1(M)).
所有这些代码,用于表示的安全逻辑否定是\u标记([\u1])
?丑
让我们看看它(至少)是否有助于上述问题(给出如此多无用答案的问题)
这不是我们想要的答案。为了了解原因,让我们看看以下类似用法的答案:
在最一般的情况下,有两个答案--这就是具体化谓词的行为方式
让我们相应地重新编码marker\u truth/2
:
marker_truth(Xs,Truth) :- subsumes_term([_,1],Xs), !, Truth = true.
marker_truth(Xs,Truth) :- Xs \= [_,1], !, Truth = false.
marker_truth([_,1],true).
marker_truth(Xs ,false) :- nonMarker__1(Xs).
nonMarker__1(T) :- var(T), !, freeze(T,nonMarker__1(T)).
nonMarker__1(T) :- T = [_|Arg], !, nonMarker__2(Arg).
nonMarker__1(_).
nonMarker__2(T) :- var(T), !, freeze(T,nonMarker__2(T)).
nonMarker__2(T) :- T = [_|_], !, dif(T,[1]).
nonMarker__2(_).
让我们使用新的i