Давая один и тот же ответ снова и снова, чем слушатель падает - Пролог - PullRequest
1 голос
/ 03 декабря 2010

Внимание, я довольно новичок в Прологе.

Я написал предикат разделения в Прологе.Он разбивает список на два новых списка.Один содержит элементы больше, чем 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-й попытки.

1 Ответ

2 голосов
/ 03 декабря 2010

Я предлагаю вам разрешить этот алгоритм по-другому:

  • Определите рекурсивный предикат (split / 4), как вы это делали, проверяя каждый элемент во входном списке, но создавайте полученные списки по возвращении рекурсии (то есть добавляйте текущий элемент в качестве заголовка соответствующего списка глава статьи).

Было бы что-то вроде этого:

split([], _, [], []).  % Base case
split([Item|Tail], Key, [Item|Small], Big):-
  Item =< Key,
  !, % Optimization, the cut here is to avoid the comparison in the next clause
  split(Tail, Key, Small, Big).
split([Item|Tail], Key, Small, [Item|Big]):-
  split(Tail, Key, Small, Big).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...