一遍又一遍地给出相同的答案,而不是侦听器崩溃 - Prolog

发布于 2024-10-06 00:21:06 字数 859 浏览 0 评论 0原文

警告,我对 Prolog 还很陌生。

我在 Prolog 中编写了一个分割谓词。它将一个列表拆分为两个新列表。一种包含大于 Key 的项目,另一种包含小于或等于 Key 的项目。它应该只返回一组答案。问题是如果我输入 ;为了检查更多答案,它不断地给我已经得到的答案,然后最终监听器崩溃。我想知道你能帮我解决这个问题吗?

代码:

split([],_,[],[]).
split([H|T],Key,Small,Big):-
    H=<Key,
    removeFirst(Small,H,NewSmall),
    split(T,Key,NewSmall,Big).
split([H|T],Key,Small,Big):-
    H>Key,
    removeFirst(Big,H,NewBig),
    split(T,Key,Small,NewBig).

removeFirst([H|T],H,T).
removeFirst(L,Key,Result):-
    divide(L,Key,F,E),
    X = F,
    Y = E,
    append(X,Y,Z),
    Result = Z.

输出:

?- split([1,2,3,4,5],3,S,B).

S = [1, 2, 3]
B = [4, 5] ;

S = [1, 2, 3]
B = [4, 5] ;

S = [1, 2, 3]
B = [4, 5] ;
侦听器在第四次尝试时崩溃。

Warning, I'm quite new to Prolog.

I've written a split predicate in Prolog. It splits a list into two new lists. One that contains items greater than Key, and one that contains items less than or equal to Key. It should only ever return one set of answers. The problem is if I type ; to check for more answers, it keeps giving me the answer I already got and then eventually the listener crashes. I was wondering if you could help me fix this?

Code:

split([],_,[],[]).
split([H|T],Key,Small,Big):-
    H=<Key,
    removeFirst(Small,H,NewSmall),
    split(T,Key,NewSmall,Big).
split([H|T],Key,Small,Big):-
    H>Key,
    removeFirst(Big,H,NewBig),
    split(T,Key,Small,NewBig).

removeFirst([H|T],H,T).
removeFirst(L,Key,Result):-
    divide(L,Key,F,E),
    X = F,
    Y = E,
    append(X,Y,Z),
    Result = Z.

Output:

?- split([1,2,3,4,5],3,S,B).

S = [1, 2, 3]
B = [4, 5] ;

S = [1, 2, 3]
B = [4, 5] ;

S = [1, 2, 3]
B = [4, 5] ;
Listener crashes on 4th attempt.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

司马昭之心 2024-10-13 00:21:06

我建议您以另一种方式解决此算法:

  • 像您一样定义一个递归谓词(split/4),检查输入列表中的每个项目,但在递归返回时构建结果列表(即将当前项目添加为子句头部相应列表的头部)。

它会是这样的:

split([], _, [], []).  % Base case
split([Item|Tail], Key, [Item|Small], Big):-
  Item =< Key,
  split(Tail, Key, Small, Big).
split([Item|Tail], Key, Small, [Item|Big]):-
  Item > Key,
  split(Tail, Key, Small, Big).

I suggest you resolve this algorithm in another way:

  • Define a recursive predicate (split/4) as you did, checking for each item in the input list, but build the resulting lists on return of recursion (that is, add the current item as the head of the appropriate list on the head of the clause).

It would be something like this:

split([], _, [], []).  % Base case
split([Item|Tail], Key, [Item|Small], Big):-
  Item =< Key,
  split(Tail, Key, Small, Big).
split([Item|Tail], Key, Small, [Item|Big]):-
  Item > Key,
  split(Tail, Key, Small, Big).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文