2013-04-01 5 views
2

Я работаю над небольшим проектом, чтобы опираться на пролог. То, что я пытаюсь сделать прямо сейчас, - это предложение, которое возвращает список слов. Итак, я беру массив символов, например. «максимумы и минимумы», и пытается разбить его на «максимумы» и «минимумы». Я использую массив символов, потому что я хочу играть со своими словами, и я не думаю, что для этого работают строки.Как я могу разбить список в прологе, учитывая точку опоры?

Вот мой код.

get_first_word([], _, []):- 
    !. 
get_first_word(X, Pivot, Input):- 
    append(X, [Pivot|_], Input), 
    !. 

split_at([],_). 
split_at(Input, Pivot):- 
    get_first_word(X, Pivot, Input), 
    writef(X), 
    append(X, Y, Input), 
    split_at(Y, Pivot). 

Проблема, которую я получаю, заключается в том, что это превращается в бесконечный цикл. В конце концов, он пройдет пустой ввод, и мой базовый регистр недостаточно хорошо написан, чтобы справиться с этим. Как это исправить?

+0

В случае, если вы планируете использовать SWI-Prolog, вы можете захотеть использовать атомы для представления слов и предложений. Затем вы можете использовать встроенные модули для анализа и построения атомов (http://www.swi-prolog.org/pldoc/doc_for?object=section(2,'4.21',swi('/doc/Manual/ manipatom.html '))), например 'atomic_list_concat/3', что в основном делает именно то, что вы описываете для атомов. –

+0

Я пытаюсь сделать простой сценарий перевода, и мне нужно будет играть с отдельными словами и словом. Могу ли я «собрать» строки с помощью SWIProlog? – UrhoKarila

+0

см. Мой ответ ниже –

ответ

1

Я думаю, что get_first_word пропустил аргумент: он должен «вернуть» и слово, и остальное, учитывая возможность того, что Pivot не появляется во входе.

Я также перенес аргументы, чтобы следовать традиционному «входному сигналу в начале, выводить в конец».

get_first_word(Input, Pivot, Word, Rest):- 
    append(Word, [Pivot|Rest], Input), !. 
get_first_word(Input, _Pivot, Input, []). 

split_at([], _). 
split_at(Input, Pivot):- 
    get_first_word(Input, Pivot, W, Rest), 
    writef(W),nl, 
    split_at(Rest, Pivot). 

тест:

?- split_at("highs and lows", 0'). 
highs 
and 
lows 
true . 
+0

Он отлично работает. Спасибо за помощь! – UrhoKarila

1

Если вы используете SWI-Prolog, то стоит учесть, используя атомы представляют собой предложения, слова, части слов и так далее. Как вы можете видеть here, вы проблема становится (если предложение представляет собой атом):

?- atomic_list_concat(Ws, ' ', 'highs and lows'). 
Ws = [highs, and, lows]. 

Есть другие полезные предикаты, например atom_concat/3 (мы можем сказать, что это append/3 для атомов), или sub_atom/5, которые могут быть полезно несколькими способами.

В качестве примечания стороны SWI-Prolog не имеет искусственного ограничения длины атомов и фактически рекомендует использовать атомы вместо строк или кодов символов.

1

При описании списков (в данном случае: списки кодов символов, которые являются вашими строками), всегда также рассматривайте использование DCG. Например:

string_pivot_tokens(Cs, P, Ts) :- phrase(tokens(Cs, P, []), Ts). 

tokens([], _, Ts)  --> token(Ts). 
tokens([C|Cs], P, Ts) --> 
     ( { C == P } -> token(Ts), tokens(Cs, P, []) 
     ; tokens(Cs, P, [C|Ts]) 
     ). 

token([])  --> []. 
token([T|Ts]) --> { reverse([T|Ts], Token) }, [Token]. 

Пример:

?- string_pivot_tokens("highs and lows", 0' , Ts), maplist(atom_codes, As, Ts). 
Ts = [[104, 105, 103, 104, 115], [97, 110, 100], [108, 111, 119, 115]], 
As = [highs, and, lows] ; 
false. 
Смежные вопросы