Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

a predicate which returns the solution path for a query in a processable form?

26 views
Skip to first unread message

Terrence Brannon

unread,
Nov 17, 2009, 3:53:34 PM11/17/09
to
Re: http://cs.union.edu/~striegnk/learn-prolog-now/html/node31.html#sec.l3.praxis

I was working problem #2 there.

I wrote one predicate to figure out whether a path exists and then
another predicate to display the path.

One would think a 'meta-predicate' could be applied to any query to
return the sequence of predicates which matched to return sucess.

I.e., my listtravel/3 predicate below should not have to be written.
Instead I think I should be able to do
solution_path_for(travel(hamilton,raglon), SolutionPath).

by(car,auckland,hamilton).
by(car,hamilton,raglan).
by(car,valmont,saarbruecken).
by(car,valmont,metz).

by(train,metz,frankfurt).
by(train,saarbruecken,frankfurt).
by(train,metz,paris).
by(train,saarbruecken,paris).

by(plane,frankfurt,bangkok).
by(plane,frankfurt,singapore).
by(plane,paris,losAngeles).
by(plane,bangkok,auckland).
by(plane,losAngeles,auckland).


travel(A,B) :- by(Method, A, B).

travel(A,B) :- by(Method, A,B1), travel(B1,B).

listtravel(A,B,[]) :- by(Method, A, B).

listtravel(A,B,[go(Method,A,B1)|MRest]) :- by(Method, A,B1), listtravel
(B1,B,MRest).

YauHsienHuang

unread,
Nov 17, 2009, 7:35:18 PM11/17/09
to
On Nov 18, 4:53 am, Terrence Brannon <metap...@gmail.com> wrote:
> One would think a 'meta-predicate' could be applied to any query to
> return the sequence of predicates which matched to return sucess.
>
> I.e., my listtravel/3 predicate below should not have to be written.
> Instead I think I should be able to do
> solution_path_for(travel(hamilton,raglon), SolutionPath).
>
> by(car,auckland,hamilton).
> by(car,hamilton,raglan).
> by(car,valmont,saarbruecken).
> by(car,valmont,metz).
...

> travel(A,B) :- by(Method, A, B).
> travel(A,B) :- by(Method, A,B1), travel(B1,B).
>
> listtravel(A,B,[]) :- by(Method, A, B).
> listtravel(A,B,[go(Method,A,B1)|MRest]) :- by(Method, A,B1), listtravel
> (B1,B,MRest).

My half-meta-predicate solution:

:- meta_predicate list_travel(3, ?, ?, -).
list_travel(Head, Path) :-
travel(A,B) = Head, by(_, A, B), !,
clause(Head, _), Path = [travel(A,B)].
list_travel(Head, [travel(A,B)|Path]) :-
clause(Head, (by(_,A,_),travel(_,Other))),
by(_, A, B), list_travel(travel(B,Other), Path).

?- list_travel(travel(frankfurt,raglan),P).
P = [travel(frankfurt, bangkok), travel(bangkok, auckland), travel
(auckland, hamilton), travel(hamilton, raglan)] ;
P = [travel(frankfurt, bangkok), travel(bangkok, auckland), travel
(auckland, hamilton), travel(hamilton, raglan)] ;
false.

Using clause/2 I could find the structure of the body of a head, and
then predicates performed are the same as travel/2.

Markus Triska

unread,
Nov 21, 2009, 4:24:05 AM11/21/09
to
Terrence Brannon <meta...@gmail.com> writes:

> I.e., my listtravel/3 predicate below should not have to be written.
> Instead I think I should be able to do
> solution_path_for(travel(hamilton,raglon), SolutionPath).

What about a meta-interpreter (MI) augmented with proof trees:

:- op(750, xfy, =>).

mi_tree(true, true) :- !.
mi_tree((A,B), (TA,TB)) :- !, mi_tree(A, TA), mi_tree(B, TB).
mi_tree(G, T => G) :- clause(G, Body), mi_tree(Body, T).

Example:

%?- mi_tree(travel(valmont, paris), T).
%@ T = ((true=>by(car, valmont, saarbruecken), (true=>by(train, saarbruecken, paris))=>travel(saarbruecken, paris))=>travel(valmont, paris)) ;
%@ T = ((true=>by(car, valmont, metz), (true=>by(train, metz, paris))=>travel(metz, paris))=>travel(valmont, paris)) ;
%@ false.

To relate such trees to intuitive paths in this example, consider:

tree_path(true) --> [].
tree_path((A,B)) --> tree_path(A), tree_path(B).
tree_path(T => G) --> tree_path(T), tree_path(G).
tree_path(by(_,A,B)) --> [A=>B].
tree_path(travel(_,_)) --> [].

Example:

%?- mi_tree(travel(valmont, paris), T), phrase(tree_path(T), Ps).
%@ T = ...,
%@ Ps = [valmont=>saarbruecken, saarbruecken=>paris] ;
%@ T = ...,
%@ Ps = [valmont=>metz, metz=>paris] ;
%@ false.

--
comp.lang.prolog FAQ: http://www.logic.at/prolog/faq/

0 new messages