обработка ввода в прологе с помощью read()

Я использую read() для ввода данных пользователем. Я планировал, что моя программа будет принимать ввод в виде

a,b,c,d,e

а затем я бы преобразовал это в список элементов. Но делая тест в прологе, я получил это

26 ?- read(X).
|: abc,def,ghi,jkl.
X = (abc, def, ghi, jkl).

Я не уверен, но это возвращает структуру? Что я могу сделать, чтобы преобразовать это в список?


person bella    schedule 12.08.2012    source источник
comment
Извините, но ссылка кажется мертвой..   -  person bella    schedule 13.08.2012
comment
исправлена ​​неработающая ссылка: чтение строки в атомарный список в прологе   -  person djf    schedule 13.08.2012


Ответы (2)


(abc, def, ghi, jkl) — это термин с функтором ',' и арностью 2. Вы можете использовать предикаты проверки термина, такие как (=..)/2, functor/3, arg/3 и т. д., чтобы разложить его, или попробуйте write_canonical/1:

?- T = (abc, def, ghi, jkl), write_canonical(T).
','(abc,','(def,','(ghi,jkl)))
T = (abc, def, ghi, jkl).

Чтобы преобразовать такие кортежи в списки, вы можете использовать DCG:

tuple_list((A,B)) --> !, tuple_list(A), tuple_list(B).
tuple_list(A)     --> [A].

Пример:

?- T = (abc, def, ghi, jkl), phrase(tuple_list(T), Ls).
T = (abc, def, ghi, jkl),
Ls = [abc, def, ghi, jkl].
person mat    schedule 12.08.2012
comment
Спасибо миллион раз, именно то, что я искал. Во время моих поисков я наткнулся на термин DCG, но так и не нашел реального примера. Еще раз СПАСИБО ВАМ - person bella; 13.08.2012

X = (abc, def, ghi, jkl).

Это набор символов; пролог не распознает не-типы (int, long, double,...).

Список представлен головой (первый элемент) и хвостом (остальные элементы). Попробуйте запустить следующие примеры:

   ?- [1,2,3,4,5,6]=[Head|Tail].
   ?- [1,2,3,4,5,6]=[First,Second|Tail].

Теперь вам нужно ознакомиться с рекурсией (это сердце пролога). Процедура вставки может выглядеть так:

   insert(X, List, [X|List]).

Но что, если список пуст; наша процедура считает, что список не является, поэтому нам нужна другая процедура, чтобы было достаточно предыдущей:

   insert(X, [], [X|]).

Мы можем сделать больше: например, проверить, присутствует ли элемент в списке:

   present(Item,[Item|_]).
   present(Item,[_|Tail]) :-
     present(Item,Tail).

Обратите внимание на рекурсию в нашей последней процедуре: present(Item, Tail) — она рекурсивно проверяет начало списка с помощью переменной Item, которую можно прочитать с клавиатуры:

   check_if_present :- read(X), present(X, List).

где List был создан ранее.

Мы также можем очень легко объединять списки:

     concatenating([],List,List).
     concatenating([Head|Tail],List,[Head|ResultedTail]) :-
      concatenating(Tail,List,ResultedTail).
person Sebi    schedule 12.08.2012