Pregunta

Actualmente estoy trabajando en un programa Prolog recursiva para enlazar rutas juntos para crear un básica GPS de la zona de Birmingham. En el momento en que puedo obtener una salida como así:

entrada

routeplan(selly_oak, aston, P).

Salida

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

Lo que me gustaría hacer es tener mi programa de proporcionar algún tipo de interfaz, por lo que si tuviera que escribir algo en la línea de:

Route from selly_oak to aston

Se me proporcionaría:

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

Prolog es un lenguaje potente, así que supongo que esto es fácilmente posible, sin embargo muchos de los libros que he sacado parecen pasar por alto esta parte. Por lo que yo soy consciente de que tengo que usar algo en la línea de escritura () y leer () aunque los detalles son desconocidos para mí.

Podría alguien aquí un novato Prolog con algunos ejemplos básicos o enlaces a más información?

EDIT: Muchas de estas respuestas parece muy complicado, donde la solución debe ser sólo alrededor de 5-10 líneas de código. La lectura en un valor que no es un problema, ya que puedo hacer algo en la línea de:

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

Yo preferiría que la salida se puede escribir utilizando escritura () por lo que una nueva línea (NL) se puede utilizar, por lo que muestra como la salida anterior.

Si este fuera mi entrada, ¿cómo iba a continuación, organizar la RoutePlan superior () para trabajar con estas entradas? Además, si tuviera que agregar las líneas para estas estaciones como un parámetro adicional de cómo sería esto, entonces puede implementar? Todos los enlaces se definen al comienzo del archivo, así:

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

Por lo tanto, con esta información, que sería bueno para ser capaz de leer la línea como tal.

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
¿Fue útil?

Solución

En este tipo de cosas, por lo general crean predicados de concha. Así, en su caso ...

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

Y print_route / 1 podría ser algo como esto recursiva:

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.

he asumido que la tercera variable de la RoutePlan / 3 predicado es una lista de listas. Además de que está construido mediante la adición a la cola. Si no lo es, debería ser bastante fácil de adaptar. Preguntar en los comentarios.

Otros consejos

Un libro que analiza este tipo de cosas en detalle es Procesamiento del Lenguaje Natural para Prolog programadores por Michael A. Covington.

En general, lo que hay que hacer es

  1. Tokenize la entrada
  2. Parse las fichas (por ejemplo con DCG) para obtener la entrada para routeplan/3
  3. Llamar <=>
  4. Generar algo de Inglés, sobre la base de la salida de <=>

Algo como esto (trabaja en 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]).

Hm, si he entendido bien lo que desea dar formato a la maravillosa lista para imprimir, no?

En SWI-Prolog esto funciona:

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).

a continuación, llamar a

output_string(P,'',_).

Es probablemente no es muy eficiente, pero hace el trabajo. :)

Aquí hay algunos predicados para leer líneas de un archivo / secuencia en una cadena de 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).

A continuación, echar un vistazo a DCG s para obtener información sobre cómo analizar una cadena.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top