Ввод в пролог - PullRequest
       24

Ввод в пролог

8 голосов
/ 24 марта 2009

В настоящее время я работаю над рекурсивной программой Prolog, которая объединяет маршруты для создания базового GPS района Бирмингема. На данный момент я могу получить вывод так:

Input

routeplan(selly_oak, aston, P).

выход

P = [selly_oak, edgbaston, ... , aston]

Я хотел бы, чтобы моя программа предоставляла какой-то интерфейс, поэтому, если бы я набрал что-то вроде:

Route from selly_oak to aston

Это даст мне:

Go from selly_oak to edgbaston
Go from edgbaston to ...
Finally, Go from ... to aston.

Пролог - мощный язык, поэтому я предполагаю, что это легко возможно, однако многие книги, которые я вынул, похоже, пропускают эту часть. Насколько я знаю, я должен использовать что-то вроде write () и read (), хотя детали мне неизвестны.

Может ли кто-нибудь из новичков Пролога привести некоторые базовые примеры или ссылки на дополнительную информацию?

РЕДАКТИРОВАТЬ: Многие из этих ответов кажутся очень сложными, где решение должно быть всего около 5-10 строк кода. Чтение значений не является проблемой, так как я могу сделать что-то вроде:

find:- 
    write('Where are you? '), 
    read(X), 
    nl, write('Where do you want to go? '),
    read(Y), 
    loopForRoute(X,Y).

Я бы предпочел, чтобы выходные данные могли быть записаны с использованием write (), чтобы можно было использовать новую строку (nl), чтобы она отображала как вывод выше.

Если бы это был мой вклад, как бы я тогда организовал top routeplan () для работы с этими входами? Кроме того, если бы я добавил линии для этих станций в качестве дополнительного параметра, как бы это тогда было реализовано? Все ссылки определены в начале файла следующим образом:

rlinks(selly_oak, edgbaston, uob_line).
rlinks(edgbaston, bham_new_street, main_line).

Следовательно, с этой информацией было бы хорошо иметь возможность прочитать строку так.

Go from selly_oak to edgbaston using the uob_line
Go from edgbaston to ... using the ...
Finally, go from ... to aston using the astuni_line

Ответы [ 4 ]

5 голосов
/ 24 марта 2009

Книга, в которой подробно рассматриваются такие вещи: Обработка естественного языка для программистов на прологах Майкл А. Ковингтон.

В общем, что вам нужно сделать, это

  1. Токенизация ввода
  2. Разобрать токены (например, с DCG), чтобы получить ввод для routeplan/3
  3. Звоните routeplan/3
  4. Создать немного английского на основе вывода routeplan/3

Примерно так (работает в SWI-Prolog):

% Usage example:
%
% ?- query_to_response('Route from selly_oak to aston', Response).
%
% Response = 'go from selly_oak to edgbaston then go from edgbaston
%         to aston then stop .'
%
query_to_response(Query, Response) :-
    concat_atom(QueryTokens, ' ', Query), % simple tokenizer
    query(path(From, To), QueryTokens, []),
    routeplan(From, To, Plan),
    response(Plan, EnglishTokens, []),
    concat_atom(EnglishTokens, ' ', Response).

% Query parser
query(path(From, To)) --> ['Route'], from(From), to(To).
from(From) --> [from], [From], { placename(From) }.
to(To) --> [to], [To], { placename(To) }.

% Response generator
response([_]) --> [stop], [.].
response([From, To | Tail]) -->
    goto(path(From, To)), [then], response([To | Tail]).
goto(path(From, To)) --> [go], from(From), to(To).

% Placenames
placename(selly_oak).
placename(aston).
placename(edgbaston).

% Mock routeplan/3
routeplan(selly_oak, aston, [selly_oak, edgbaston, aston]).
4 голосов
/ 24 марта 2009

Хм, если я вас правильно понял, вы просто хотите отформатировать список для печати, не так ли?

В SWI-Prolog это работает:

output_string([A,B],StrIn,StrOut) :-
 concat_atom([StrIn, 'Finally, Go from ', A, ' to ', B, '.'],StrOut),
 write(StrOut).

output_string([A,B|Rest],StrIn,StrOut) :-
 concat_atom([StrIn,'Go from ', A, ' to ', B, '.\n'],StrAB),
 output_string([B|Rest],StrAB,StrOut).

затем позвоните с

output_string(P,'',_).

Это, вероятно, не очень эффективно, но это делает работу. :)

2 голосов
/ 02 апреля 2009

Для такого рода вещей я обычно создаю предикаты оболочки. Так что в вашем случае ...

guided:-
    print('Enter your start point'),nl,
    read(Start),
    print('Enter your destination'),nl,
    read(Dest),
    routeplan(Start, Dest, Route),
    print_route(Route).

И print_route / 1 может быть чем-то рекурсивным, например так:

print_route([]).

print_route([[A,B,Method]|Tail]):-
    print_route(Tail),
    print('Go from '), print(A),
    print(' to '), print(B),
    print(' by '), print(Method), nl.

Я предположил, что третья переменная предиката routeplan / 3 - это список списков. Кроме того, что он построен путем добавления к хвосту. Если это не так, это должно быть довольно легко адаптироваться. Спросите в комментариях.

0 голосов
/ 24 марта 2009

Вот несколько предикатов для чтения строк из файла / потока в строку Prolog:

%%% get_line(S, CL): CL is the string read up to the end of the line from S.
%%% If reading past end of file, returns 'end_of_file' in CL first, raises
%%% an exception second time.
%%% :- pred get_string(+stream, -list(int)).
get_line(S, CL) :-
    peek_code(S, C),
    (   C = -1
    ->  get_code(S, _),
        CL = end_of_file
    ;   get_line(S, C, CL)).

get_line(_, -1, CL) :- !, CL = [].  % leave end of file mark on stream
get_line(S, 0'\n, CL) :- !,
    get_code(S, _),
    CL = [].
get_line(S, C, [C|CL]) :-
    get_code(S, _),
    peek_code(S, NC),
    get_line(S, NC, CL).

%% read_lines(L): reads lines from current input to L.  L is a list of list
%% of character codes, newline characters are not included.
%% :- pred read_lines(-list(list(char))).
read_lines(L) :-
    current_input(In),
    get_line(In, L0),
    read_lines(In, L0, L).

%% read_lines(F, L): reads lines from F to L.  L is a list of list of character
%% codes, newline characters are not included.
%% :- pred read_lines(+atom, -list(list(char))).
read_lines(F, L) :-
    fail_on_error(open(F, read, S)),
    call_cleanup((get_line(S, L0),
              read_lines(S, L0, L)),
             close(S)).

read_lines(_, end_of_file, L) :- !, L = [].
read_lines(S, H, [H|T]) :-
    get_line(S, NH),
    read_lines(S, NH, T).

Затем посмотрите на DCG s для получения информации о том, как анализировать строку.

...