Domanda

Al momento sto lavorando su un programma Prolog ricorsivo di collegare percorsi insieme per creare un base GPS della zona di Birmingham. Al momento posso ottenere in uscita come:

ingresso

routeplan(selly_oak, aston, P).

Output

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

Quello che vorrei fare è di avere il mio programma di fornire una sorta di interfaccia, quindi se dovessi digitare qualcosa sulla falsariga di:

Route from selly_oak to aston

Sarebbe fornire me con:

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

Prolog è un linguaggio potente quindi presumo questo è facilmente possibile, tuttavia molti dei libri che ho preso fuori sembrano saltare questa parte. Per quanto ne so io devo usare qualcosa sulla falsariga di write () e leggere (), anche se i dettagli sono a me sconosciuti.

Si poteva qui un novizio Prolog fuori con alcuni esempi di base o link ad altre eventuali informazioni?

Modifica Un sacco di queste risposte sembrano molto complicato, in cui la soluzione deve essere solo circa 5-10 righe di codice. Leggendo in un valore non è un problema, come posso fare qualcosa sulla falsariga di:

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

Io preferirei che se l'uscita potrebbe essere scritta utilizzando write () in modo da una nuova linea (nl) può essere utilizzato, in modo da visualizzare come l'uscita di cui sopra.

Se questo fosse il mio ingresso, come faccio poi organizzare il routeplan superiore () per lavorare con questi ingressi? Inoltre, se dovessi aggiungere le linee per queste stazioni come un parametro in più come sarebbe questo allora essere attuata? Tutti i collegamenti sono definiti all'inizio del file in questo modo:

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

Pertanto, con queste informazioni, sarebbe bello per essere in grado di leggere la linea come modo.

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
È stato utile?

Soluzione

Per questo genere di cose, io di solito creare predicati shell. Quindi nel tuo caso ...

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

E print_route / 1 potrebbe essere qualcosa di simile ricorsiva:

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.

Ho pensato che il 3 ° variabile del routeplan / 3 predicato è una lista di liste. Inoltre che è costruito con l'aggiunta alla coda. Se non lo è, dovrebbe essere abbastanza facile da adattare. Chiedi nei commenti.

Altri suggerimenti

Un libro in cui si discute queste cose in dettaglio è Natural Language Processing per Prolog programmatori da Michael A. Covington.

In generale, ciò che devi fare è

  1. Tokenize l'ingresso
  2. Parse i token (ad esempio con DCG) per ottenere l'input per routeplan/3
  3. Chiama <=>
  4. Genera un po 'inglese, sulla base della produzione di <=>

Qualcosa di simile (lavora in 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, se ho capito bene che si desidera solo per formattare l'elenco piacevolmente per la stampa, no?

In SWI-Prolog questo funziona:

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

quindi chiamare con

output_string(P,'',_).

Probabilmente non è molto efficiente, ma non il lavoro. :)

Ecco alcuni predicati per leggere le linee da un file / flusso in una stringa 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).

Quindi, dare un'occhiata a DCG s per informazioni su come analizzare una stringa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top