Going from one point to another

4

With the following facts,

x(p1,d1,c,d,e,f),
y(d1,d2,i,j,k,l),
z(d2,d3,o,p,q,r),

Think of them as points, I would like to know how I can go from x to z, by inputting p1 and d3.

I have, for example:

write('Partida: '),nl,
read(Partida_it),
write('Destino: '),nl,
read(Destino_it),
    viagem(Partida_it,Destino_it,C,D,E,F),nl,
    write(Partida_it),write('<-->'),write(Destino_it),nl,
write('Tipo: '),write(C),nl,
write('Hora de partida: '),write(D),nl,
write('Hora de chegada: '),write(E),nl,
write('Preco: '),write(F),nl,
    fail,

In case this trip already exists ^

viagem(Partida_it,B,C,D,_,P1),nl,
viagem(B,Destino_it,F,_,E,P2),nl,
P is P1+P2,
write(Partida_it),write('<-->'),write(Destino_it),nl,
write('Tipo: '),write(C),write('e'),write(F),nl,
write('Hora de partida: '),write(D),nl,
write('Hora de chegada: '),write(E),nl,
write('Preco: '),write(P),nl,
    fail.

I've been stuck with this problem for a couple of hours now.

    
asked by anonymous 15.05.2015 / 22:49

1 answer

4

Its logic, at a high level, would be as follows:

  • If there is a journey from Partida to Destino , do it and that's it;
  • Otherwise, travel to a point X you have not visited , and then try to travel from X to Destino .
  • Verify that you have visited X or is not important, otherwise you can enter an infinite loop. This can be done by saving the points you've already passed in a list, and by choosing a destination by checking whether or not that point is in the list.

    In code:

    viajar(A, B, _, [viagem(A, B, C, D, E, F)]) :-
        viagem(A, B, C, D, E, F), % Se existe uma viagem direta de A a B
        !.                        % Não precisa procurar mais
    
    viajar(A, B, JaVisitou, [viagem(A, X, C, D, E, F)|Lista]) :-
        viagem(A, X, C, D, E, F),           % Escolhe um destino qualquer
        \+ member(X, JaVisitou),            % Que você ainda não visitou
        viajar(X, B, [X|JaVisitou], Lista). % E tente ir dele até B
    

    The result of a call passing Partida and Destino would be a list of all trips that have to be made:

    ?- viajar(roma, porto, [roma], Lista).
    Lista = [viagem(roma, lisboa, aviao, 12:00, 15:00, 300), viagem(lisboa, porto, comboio, 16:00, 18:00, 10)]
    

    Example on ideone . From there you can do operations in this list, type print all the steps:

    passos([]).
    passos([viagem(A,B,C,D,E,F)|R]) :-
        write(A),write('<-->'),write(B),nl,
        write('Tipo: '),write(C),nl,
        write('Hora de partida: '),write(D),nl,
        write('Hora de chegada: '),write(E),nl,
        write('Preco: '),write(F),nl,
        passo(R).
    

    And calculate the total price:

    preco([], 0).
    preco([viagem(_,_,_,_,_,P)|R], Total) :-
        preco(R, X),
        Total is P + X.
    

    Etc. Note: In the examples above, I did not use tail recursion, to make the answer simpler and logic clear. In practice, you should use accumulators instead of doing additional operations after the recursive call.

        
    15.05.2015 / 23:41