For Programmers: Free Programming Magazines  


Home > Archive > Prolog > April 2007 > Prolog beginner









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 Prolog beginner
phamtrungthanh@gmail.com

2007-04-13, 4:03 am

I have a problem when doing my Prolog assignment, Can someone give me
some hints?

I have a price database:

price(a,1).
price(b,2).
price(c,4).

the problem is find the item with max(or min) price in one query (no
helper predicates except some common ones like append, member...).

Could someone give me some hints ?

thank you,

Reuben Grinberg

2007-04-13, 4:03 am

phamtrungthanh@gmail.com wrote:
> I have a problem when doing my Prolog assignment, Can someone give me
> some hints?
>
> I have a price database:
>
> price(a,1).
> price(b,2).
> price(c,4).
>
> the problem is find the item with max(or min) price in one query (no
> helper predicates except some common ones like append, member...).
>
> Could someone give me some hints ?
>
> thank you,
>


by
> no helper predicates except some common ones like append, member...).


do you mean that other predicates are not available or that you aren't
allowed to make them?

I'm going to try to help you without giving you the answer and if you
need more help, ask.

The first thing I would do (but others on this list might have a better
way) is to aggregate the prices into a list somehow. One way to do this
is to use the findall predicate:
findall(price(I,P), price(I,P), L).
L = [price(a,1),price(b,2),price(c,4)] ? ;

Now that you have a list, you can operate on the list and try to find
the item with the biggest number.


Here is one way you can do that.

In many functional languages, there is a function called fold (sometimes
it's called reduce or inject) that takes a list and a function that
takes two arguments:

fold( [1,2,3,4], some_function )

For now, let some_function be the operator '+', that takes two numbers
and adds them together to get a new number.

What fold does is first apply + to the first two elements in the list:
0: fold ( [1,2,3,4], +)
1: fold ( [1+2,3,4], +)

and then continues doing this, applying the function to the result of
the last computation and the next element in the list:
2: fold ([1+2+3,4], +)

3: fold([1+2+3+4], +)

and the result is 1+2+3+4 = 7.

So fold(list, +) adds up all the numbers.
Likewise, fold(list, *) multiplies all the numbers together.

Here is one way to implement a similar idea in prolog:

sum([], 0).
sum([H|T], Result) :- sum(T, Rest), Result is H + Rest.

and product:

prod([], 1).
prod([H|T], Result) :- prod(T,Rest), Prod is H * Result.


Now here is the most important hint for your assignment:
The function that you fold over the list doesn't necessarily have to
combine the numbers in some way (+, *, /, etc...). The function can just
choose one of the numbers.

Here is one more thing which will may you:

max(A,B,A) :- A > B.
max(A,B,B) :- B >= A.

I hope these hints help you. Ask if you need more help.

Cheers,
Reuben


phamtrungthanh@gmail.com

2007-04-13, 4:03 am

Thank you very much for your answer. You should replace all TAs at my
school !!!!!

I did exactly what you said and what I came up with:

maxL([], Imax, Pmax, Imax, Pmax).
maxL([[I,P] | X], Imax, Pmax, I1, P1) :- (P > Pmax) -> maxL(X, I, P,
I1, P1); maxL(X, Imax, Pmax, I1, P1).

and I intend to construct a query like (because the requirement is
"one query")

maxL( findall([I,P], price(I,P), L), a, -1, A, B).


and it seemed not to work. But if I have maxL( [[a,1], [b, 4]], a, -1,
A, B ). It will return correct answers. So one last question is how I
make it into one query ?






Reuben Grinberg

2007-04-13, 10:02 pm

phamtrungthanh@gmail.com wrote:
> Thank you very much for your answer. You should replace all TAs at my
> school !!!!!
>
> I did exactly what you said and what I came up with:
>
> maxL([], Imax, Pmax, Imax, Pmax).
> maxL([[I,P] | X], Imax, Pmax, I1, P1) :- (P > Pmax) -> maxL(X, I, P,
> I1, P1); maxL(X, Imax, Pmax, I1, P1).
>
> and I intend to construct a query like (because the requirement is
> "one query")
>
> maxL( findall([I,P], price(I,P), L), a, -1, A, B).
>
>
> and it seemed not to work. But if I have maxL( [[a,1], [b, 4]], a, -1,
> A, B ). It will return correct answers. So one last question is how I
> make it into one query ?
>
>


Remember that predicates in prolog aren't functions and don't return
values besides true or false. So you don't want to put findall inside of
maxL. You want to put the List generated from findall into maxL:

find_biggest(A,B) :- findall([I,P], price(I,P), L), maxL(L, a, -1, A, B).

Glad you found my answer useful.

Cheers,
Reuben
John Fletcher

2007-04-13, 10:02 pm

phamtrungthanh@gmail.com wrote:
> I have a problem when doing my Prolog assignment, Can someone give me
> some hints?
>
> I have a price database:
>
> price(a,1).
> price(b,2).
> price(c,4).
>
> the problem is find the item with max(or min) price in one query (no
> helper predicates except some common ones like append, member...).
>
> Could someone give me some hints ?
>


You could translate the following into Prolog:

- An item has the maximum price if there is no item with a higher price.

- An item has the minimum price if there is no item with a lower price.

Regards

Reuben Grinberg

2007-04-14, 4:03 am

John Fletcher wrote:
> phamtrungthanh@gmail.com wrote:
>
> You could translate the following into Prolog:
>
> - An item has the maximum price if there is no item with a higher price.
>
> - An item has the minimum price if there is no item with a lower price.
>
> Regards
>


Just wondering -- is there a way to do this without using findall?
bart demoen

2007-04-14, 4:03 am

On Sat, 14 Apr 2007 01:34:13 -0500, Reuben Grinberg wrote:


> Just wondering -- is there a way to do this without using findall?


min_list(List,Min) :-
member(Min,List), \+( (member(Other,List), Other < Min) ).

Generalise appropriately.

BTW, one can do "findall without findall/3" very often as well -
just Google for it :-)

Cheers

Bart Demoen
Jan Wielemaker

2007-04-14, 10:05 pm

On 2007-04-14, bart demoen <bmd@cs.kuleuven.be> wrote:
> On Sat, 14 Apr 2007 01:34:13 -0500, Reuben Grinberg wrote:
>
>
>
> min_list(List,Min) :-
> member(Min,List), \+( (member(Other,List), Other < Min) ).
>
> Generalise appropriately.


I missed the start, but what is wrong with this if you really
don't want to type a loop:

min_list(List, Min) :-
sort(List, [Min|_]).

--- Jan
bart demoen

2007-04-14, 10:05 pm

On Sat, 14 Apr 2007 15:28:22 +0000, Jan Wielemaker wrote:

> On 2007-04-14, bart demoen <bmd@cs.kuleuven.be> wrote:
>
> I missed the start, but what is wrong with this if you really
> don't want to type a loop:
>
> min_list(List, Min) :-
> sort(List, [Min|_]).
>
> --- Jan


Jan, please don't turn a fishing course into a fish :-)

What's wrong with your solution is that it doesn't generalise
to the case where the List is something you would get by a findall
and the member goal would be the generator in the findall ...
ah, what the heck, too complicated ... you should read the question to
which I answered !

Cheers

Bart Demoen

A.L.

2007-04-14, 10:05 pm

On Sat, 14 Apr 2007 08:22:32 +0200, bart demoen <bmd@cs.kuleuven.be>
wrote:

>On Sat, 14 Apr 2007 01:34:13 -0500, Reuben Grinberg wrote:
>
>
>
>min_list(List,Min) :-
> member(Min,List), \+( (member(Other,List), Other < Min) ).
>
>Generalise appropriately.
>
>BTW, one can do "findall without findall/3" very often as well -
>just Google for it :-)
>


Unfortunately, this

Findall without findall/3

Proceedings of the tenth international conference on logic programming
on Logic programming table of contents

Budapest, Hungary
Pages: 408 - 423
Year of Publication: 1993
ISBN:0-262-73105-3
Authors André Mariën
Bart Demoen

Is not available on line other way than from acm portal....

A.L.

bart demoen

2007-04-15, 4:03 am

On Sat, 14 Apr 2007 13:07:24 -0500, A.L wrote:


> Unfortunately, this
>
> Findall without findall/3
>
> Is not available on line other way than from acm portal....
>
> A.L.


It is now at http://www.cs.kuleuven.be/~bmd/findall_iclp_proc.ps
for a short time. Let me know if that worked for you.

Cheers

Bart Demoen
A.L.

2007-04-15, 7:04 pm

On Sun, 15 Apr 2007 09:11:33 +0200, bart demoen <bmd@cs.kuleuven.be>
wrote:

>On Sat, 14 Apr 2007 13:07:24 -0500, A.L wrote:
>
>
>
>It is now at http://www.cs.kuleuven.be/~bmd/findall_iclp_proc.ps
>for a short time. Let me know if that worked for you.
>


Got it, thanks!

A.L.
Sponsored Links







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

Copyright 2008 codecomments.com