For Programmers: Free Programming Magazines  


Home > Archive > Prolog > March 2005 > A particular 'splitting' problem









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author A particular 'splitting' problem
Eddie Jobson

2005-03-09, 3:59 pm

Suppose I have a prolog program, and I want to extract all the bodies
related to a particular head. I used the query:

setof(Body, clause(Headname, Body), Output).

How can I obtain a list from Output where every element is exacly a
single literal?

Quick example:

....
can_read(Book) :- available(Book).
can_read(Book) :- stock(Book), x(Book).
can_read(Book) :- a(Book), b(Book), c(Book).
....

the query above gives

Output = [available(_G441), (a(_G441), b(_G441), c(_G441)),
(stock(_G441), x(_G441))]

but I need:

[available(_G441), a(_G441), b(_G441), c(_G441), stock(_G441),
x(_G441)]

Thanks in advance!
Nameless

2005-03-09, 3:59 pm

"Eddie Jobson" <mirrormaze@inwind.it> wrote in message
news:aefda4a.0503090723.197a905b@posting.google.com...
> Suppose I have a prolog program, and I want to extract all the
> bodies related to a particular head. I used the query:
>
> setof(Body, clause(Headname, Body), Output).
>
> How can I obtain a list from Output where every element is
> exacly a single literal?
>
> Quick example:
>
> ...
> can_read(Book) :- available(Book).
> can_read(Book) :- stock(Book), x(Book).
> can_read(Book) :- a(Book), b(Book), c(Book).
> ...
>
> the query above gives
>
> Output = [available(_G441), (a(_G441), b(_G441), c(_G441)),
> (stock(_G441), x(_G441))]
>
> but I need:
>
> [available(_G441), a(_G441), b(_G441), c(_G441), stock(_G441),
> x(_G441)]


Looks like you need a 'flatten' predicate. If it's not
available in your Prolog, you'll definitely find some code
on the web, look for flatten. Oh what the hell, I have one
version on hand so let's be generous:

% flatten(+List1, ?List2)
% Is true when List2 is a non nested version of List1.
% Author: Jan Wielemaker

flatten(List, FlatList) :-
flatten(List, [], FlatList0),
!,
FlatList = FlatList0.

flatten(Var, Tl, [Var|Tl]) :-
var(Var),
!.
flatten([], Tl, Tl) :-
!.
flatten([Hd|Tl], Tail, List) :-
flatten(Hd, FlatHeadTail, List),
flatten(Tl, Tail, FlatHeadTail).
flatten(Atom, Tl, [Atom|Tl]).

Run this after setof, substituting Output for List1.


vannoord@let.rug.nl

2005-03-09, 3:59 pm

Nameless <news.mail@chello.no> wrote:
> "Eddie Jobson" <mirrormaze@inwind.it> wrote in message
> news:aefda4a.0503090723.197a905b@posting.google.com...
[color=darkred]
> Looks like you need a 'flatten' predicate. If it's not
> available in your Prolog, you'll definitely find some code
> on the web, look for flatten. Oh what the hell, I have one
> version on hand so let's be generous:


> % flatten(+List1, ?List2)
> % Is true when List2 is a non nested version of List1.
> % Author: Jan Wielemaker


> flatten(List, FlatList) :-
> flatten(List, [], FlatList0),
> !,
> FlatList = FlatList0.


> flatten(Var, Tl, [Var|Tl]) :-
> var(Var),
> !.
> flatten([], Tl, Tl) :-
> !.
> flatten([Hd|Tl], Tail, List) :-
> flatten(Hd, FlatHeadTail, List),
> flatten(Tl, Tail, FlatHeadTail).
> flatten(Atom, Tl, [Atom|Tl]).


> Run this after setof, substituting Output for List1.



except you need to flatten conjunctions, not lists.




--
Gertjan van Noord Alfa-informatica, RUG, Postbus 716, 9700 AS Groningen
vannoord at let dot rug dot nl http://www.let.rug.nl/~vannoord
Nameless

2005-03-09, 3:59 pm

"Nameless" wrote in message
news:H7FXd.4334$Mw3.2266@amstwist00...
> "Eddie Jobson" <mirrormaze@inwind.it> wrote in message
> news:aefda4a.0503090723.197a905b@posting.google.com...
>
> Looks like you need a 'flatten' predicate. If it's not
> available in your Prolog, you'll definitely find some code
> on the web, look for flatten. Oh what the hell, I have one
> version on hand so let's be generous:
>
> % flatten(+List1, ?List2)
> % Is true when List2 is a non nested version of List1.
> % Author: Jan Wielemaker
>
> flatten(List, FlatList) :-
> flatten(List, [], FlatList0),
> !,
> FlatList = FlatList0.
>
> flatten(Var, Tl, [Var|Tl]) :-
> var(Var),
> !.
> flatten([], Tl, Tl) :-
> !.
> flatten([Hd|Tl], Tail, List) :-
> flatten(Hd, FlatHeadTail, List),
> flatten(Tl, Tail, FlatHeadTail).
> flatten(Atom, Tl, [Atom|Tl]).
>
> Run this after setof, substituting Output for List1.


Whoops, this is not quite true since setof didn't give you
nested _lists_. But it's so similar that you should be able
to adapt flatten to split up the second term in the list.


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com