Question

Je travaille actuellement sur un programme Prolog récursive pour relier les itinéraires pour créer un base GPS de la région de Birmingham. En ce moment je peux obtenir une sortie comme ceci:

Entrée

routeplan(selly_oak, aston, P).

Sortie

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

Ce que je voudrais faire est d'avoir mon programme fournir une sorte d'interface, donc si je devais taper quelque chose le long des lignes de:

Route from selly_oak to aston

Il me fournirait:

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

Prolog est un langage puissant, donc je suppose que cela est facilement possible, mais la plupart des livres que j'ai pris semblent en ignorer cette partie. Pour autant que je suis conscient que je dois utiliser quelque chose le long des lignes d'écriture () et lire (), bien que les détails me sont inconnus.

Quelqu'un pourrait-il ici un novice Prolog avec quelques exemples de base ou des liens vers des informations supplémentaires?

EDIT: Beaucoup de ces réponses semblent très compliquées, où la solution ne devrait être autour de 5-10 lignes de code. La lecture d'une valeur n'est pas un problème que je peux faire quelque chose le long des lignes de:

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

Je préférerais que la sortie pourrait être écrit à l'aide d'écriture () pour une nouvelle ligne (nl) peut être utilisé, de sorte qu'il affiche comme la sortie ci-dessus.

Si tel était mon entrée, comment pourrais-je travailler puis arranger avec ces entrées haut RoutePlan ()? De plus, si je devais ajouter les lignes pour ces stations comme un paramètre supplémentaire comment serait alors mis en œuvre? Tous les liens sont définis au début du fichier comme ceci:

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

Par conséquent, avec ces informations, il serait bon de pouvoir lire la ligne comme ainsi.

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
Était-ce utile?

La solution

Pour ce genre de chose, je crée habituellement prédicats shell. Donc, dans votre cas ...

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

Et print_route / 1 pourrait être quelque chose récursif comme ceci:

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.

J'ai supposé que la 3e variable du prédicat RoutePlan / 3 est une liste de listes. En outre qu'il est construit en ajoutant à la queue. Si ce n'est pas, il devrait être assez facile à adapter. Demandez dans les commentaires.

Autres conseils

Un livre qui traite de ces choses en détail est Traitement du langage naturel pour les programmeurs Prolog par Michael A. Covington.

En général, ce que vous devez faire est

  1. Tokenize l'entrée
  2. analyser le jeton (par exemple avec DCG) pour obtenir l'entrée pour routeplan/3
  3. Appel <=>
  4. Générer un peu l'anglais sur la base de la sortie de <=>

Quelque chose comme ça (fonctionne dans 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 je vous comprends bien, vous voulez juste formater la liste bien pour l'impression, non?

Dans SWI-Prolog ceci fonctionne:

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

puis appelez avec

output_string(P,'',_).

Il est probablement pas très efficace, mais il fait le travail. :)

Voici quelques prédicats à lire les lignes d'un fichier / flux dans une chaîne 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).

Alors, jetez un oeil à DCG s des informations sur comment analyser une chaîne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top