Pergunta

Atualmente estou trabalhando em um programa Prolog recursiva para rotas de ligação juntos para criar um básico GPS da área de Birmingham. No momento em que eu posso obter uma saída assim:

Input

routeplan(selly_oak, aston, P).

saída

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

O que eu gostaria de fazer é ter meu programa de fornecer algum tipo de interface, por isso, se eu fosse para digitar algo ao longo das linhas de:

Route from selly_oak to aston

Ele me proporcionaria:

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

Prolog é uma linguagem poderosa, então eu suponho que este é facilmente possível, no entanto muitos dos livros que eu retirados parecem pular esta parte. Tanto quanto eu estou ciente que eu tenho que usar algo ao longo das linhas de write () e read () embora os detalhes são desconhecidos para mim.

Será que alguém aqui um novato Prolog com alguns exemplos básicos ou links para mais informações?

EDIT: Muitas dessas respostas parecer muito complicado, onde a solução deve ser apenas em torno de 5-10 linhas de código. Leitura em um valor não é um problema como eu posso fazer algo ao longo das linhas de:

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

Eu preferia que a saída poderia ser escrito usando write () para uma nova linha (NL) pode ser usado, para que ele exiba como a saída acima.

Se esta fosse a minha entrada, como eu, em seguida, organizar o topo routeplan () para trabalhar com estas entradas? Além disso, se eu fosse para adicionar as linhas para essas estações como um parâmetro extra como isso, então, ser implementado? Todos os links são definidos no início do arquivo assim:

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

Portanto, com esta informação, que seria bom para ser capaz de ler a linha 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
Foi útil?

Solução

Para esse tipo de coisa, eu costumo criar predicados de fachada. Assim, no seu 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 poderia ser algo recursiva como esta:

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.

Eu tenho assumido que a terceira variável do predicado routeplan / 3 é uma lista de listas. Também que ele é construído adicionando à cauda. Se não for, deve ser bastante fácil de se adaptar. Pergunte nos comentários.

Outras dicas

Um livro que discute tais coisas em detalhes é Processamento de Linguagem Natural para Prolog Programadores por Michael A. Covington.

Em geral, o que você precisa fazer é

  1. Tokeniza a entrada
  2. analisar os símbolos (por exemplo com DCG) para obter a entrada para routeplan/3
  3. routeplan/3 Chamada
  4. Gerar um pouco de Inglês na base da produção de routeplan/3

algo assim (obras em 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 eu entendi você só quer formatar a lista bem para imprimir, não?

Em SWI-Prolog isso 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).

em seguida, chamar com

output_string(P,'',_).

Provavelmente não é muito eficiente, mas ele faz o trabalho. :)

Aqui estão alguns predicados para ler linhas de um arquivo / fluxo para uma string 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).

Em seguida, dê uma olhada DCG s para obter informações sobre como analisar uma string.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top