我不完全确定你想在这里做什么。例如,split(5, [1,2,3,4,5])
应该做什么?就此而言,假设输入列表已排序是否安全?我会这样假设。
您的规则的基本问题split/2
是您没有任何输出参数。Prolog 的工作方式与大多数编程语言不同;没有这样的东西return
。起初这感觉像是一个严重的限制,但 Prolog 实际上允许您“返回”任意数量的结果。看看这段代码,在我看来,你对这种理解的理解已经到了一半,因为你有split/2
which 似乎没有任何 out 参数,但它调用split/4
了你需要的两个 out 参数。
对于初学者,我会放弃split/2
并尝试开始split/4
工作。你所拥有的在那里看起来并不太疯狂:
?- split(2, [1,2,3,4,5], X, Y).
X = [1, 2],
Y = [3, 4, 5] .
?- split(5, [1,2,3,4,5], X, Y).
X = [1, 2, 3, 4, 5],
Y = [] .
?- split(1, [1,2,3,4,5], X, Y).
X = [1],
Y = [2, 3, 4, 5] .
这表明您的大多数规则都是正确的。您遇到麻烦的地方是其他解决方案:
?- split(2, [1,2,3,4,5], X, Y).
... ;
2 [3,4,5]
X = [1, 2|_G317] ;
false.
?- split(5, [1,2,3,4,5], X, Y).
... ;
5 []
X = [1, 2, 3, 4, 5|_G326] ;
false.
?- split(1, [1,2,3,4,5], X, Y).
... ;
1 [2,3,4,5]
X = [1|_G314].
您可以从那里的写作中看到,这些额外的解决方案是由您的最后一条规则生成的,X = Y, write(Y)...
等等。只需删除该规则即可在split/4
.
继续前进,我认为可能而不是split/2
您真正想要的是split/3
一个输出参数,一个列表列表。根据我们目前所拥有的,生成它并不难:
split(X, List, [Before, After]) :- split(X, List, Before, After).
运行它,我们看到我们得到了您提到的预期结果:
?- split(3, [1,2,3,4,5], X).
X = [[1, 2, 3], [4, 5]] ;
false.
?- split(1, [1,2,3,4,5], X).
X = [[1], [2, 3, 4, 5]] ;
false.
?- split(5, [1,2,3,4,5], X).
X = [[1, 2, 3, 4, 5], []] ;
false.
希望这可以帮助!