【问题标题】:Giving same answer over and over, than listener crashes - Prolog一遍又一遍地给出相同的答案,而不是听众崩溃 - Prolog
【发布时间】:2010-12-03 10:10:57
【问题描述】:

警告,我是 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] ;
侦听器在第 4 次尝试时崩溃。

【问题讨论】:

    标签: prolog


    【解决方案1】:

    我建议你用另一种方式解决这个算法:

    • 定义递归谓词 (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).
    

    【讨论】:

    • +1;这也是我编写这样一个谓词的方式。如果您不想使用 cut (!) 来获得纯度,只需将测试 Item &gt; Key 作为 split/4 的最后一个子句的第一个子目标就足够了,就像 OP 最初所做的那样。
    • split([1],1,[1],Grs). 正确成功,split([1],1,[],Grs). 错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 2019-04-16
    • 2016-12-20
    相关资源
    最近更新 更多