For Programmers: Free Programming Magazines  


Home > Archive > Prolog > April 2004 > Again on polymorphism.









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 Again on polymorphism.
seguso

2004-04-19, 5:52 pm

Hello again, :-)

At first, it seems you can mimick polymorphism (duck typing) in prolog this
way:

% this is a polymorphic predicate. It can be applied to any X for which
% width/2 and height/2 are defined.
area( X, A):-
width(X, W),
height(X, H),
A is W*H.


width(ship( W, _, _Passengers), W).
height(ship( _, H, _Passengers), H).
width(plane( W, _), W).
height(plane( _, H), H).


Now I can have a list of intermixed planes and ships, and still apply area/2
to all members of the list:

maplist(area, [plane(32,3), ship(2,3,4)], Areas).


But this approach cannot be used when the polymorphic predicate must modify
the argument! I mean:


% walk/2: I want walk/2 to be polymorphic, i.e. to apply to any X for
% which speed/2 and position/2 are defined.
walk(X, NewX):-
speed(X, S),
position(X, P),
NewPosition is P + S,
NewX = ????


I need to call walk/2 both with X = ship(3,4,5) and with X = plane(3,4).
What I need to say is "let NewX = a copy of X where the position has been
replaced by NewPosition".

Is there a way to do that?

Thanks a lot! ^_^

Maurizio

--
Best Regards,
Maurizio Colucci
Please remove the uppercase letters "S,P,A,M":
seSgPuAsMo.forever@tin.it
Nick Wedd

2004-04-20, 7:39 am

In message <9EWgc.105872$rM4.4180484@news4.tin.it>, seguso
<look@in.signature> writes
>Hello again, :-)
>
>At first, it seems you can mimick polymorphism (duck typing) in prolog this
>way:
>
> % this is a polymorphic predicate. It can be applied to any X for which
> % width/2 and height/2 are defined.
> area( X, A):-
> width(X, W),
> height(X, H),
> A is W*H.
>
>
> width(ship( W, _, _Passengers), W).
> height(ship( _, H, _Passengers), H).
> width(plane( W, _), W).
> height(plane( _, H), H).
>
>
>Now I can have a list of intermixed planes and ships, and still apply area/2
>to all members of the list:
>
> maplist(area, [plane(32,3), ship(2,3,4)], Areas).
>
>
>But this approach cannot be used when the polymorphic predicate must modify
>the argument! I mean:
>
>
> % walk/2: I want walk/2 to be polymorphic, i.e. to apply to any X for
> % which speed/2 and position/2 are defined.
> walk(X, NewX):-
> speed(X, S),
> position(X, P),
> NewPosition is P + S,
> NewX = ????
>
>
>I need to call walk/2 both with X = ship(3,4,5) and with X = plane(3,4).
>What I need to say is "let NewX = a copy of X where the position has been
>replaced by NewPosition".
>
>Is there a way to do that?


You need to start by deciding what a ship looks like. Yours as above is
ship( Width, Height, Passengers )
with no position. I would prefer
object( Type, Name, Position, Speed )
Position and Speed have the form X/Y for a ship, X/Y/Z for a plane.

Then we can have

walk( object(ship,N,P,S), object(ship,N,NewP,S) ):-
add2( P, S, NewP ).
add2( X/Y, DX/DY, NewX/NewY ) :-
NewX is X + DX,
NewY is Y + DY.

walk( object(plane,N,P,S), object(plane,N,NewP,NewS) ):-
add3( P, S, NewP ),
fall( S, NewS ).
add3( X/Y/Z, DX/DY/DZ, NewX/NewY/NewZ ) :-
NewX is X + DX,
NewY is Y + DY,
NewZ is Z + DZ.
fall( DX/DY/DZ, DX/DY/NewDZ ) :-
gravitationalconstant( G ),
NewDZ is DZ - G.

The properties of an object which change (position and speed) get
carried around in your list, while the static properties are kept in
facts like
width( nancy, 20 ).
height( nancy, 40 ).
passengers( nacy, 300 ).
nancy here is the ship's name, an atom, which no other object has.

Nick
--
Nick Wedd nick@maproom.co.uk
seguso

2004-04-20, 10:52 am

Nick Wedd wrote:

>
> You need to start by deciding what a ship looks like.__Yours_as_above_is
> ship(_Width,_Height,_Passengers_)
> with no position.__I_would_prefer
> object(_Type,_Name,_Position,_Speed_)
> Position and Speed have the form X/Y for a ship, X/Y/Z for a plane.
>


Thank you very much, but this is not what I wanted. I have ship/3 and
plane/2 (ship and plane differ in number and meaning of the arguments), and
I want to write walk/2 only once (you wrote two versions of walk/2), and it
must work for both ship and plane. Finally, I want walk/2 to work for any
term for which speed/2, position/2, and possibly something else, is
defined.

The solution I found was so easy I am a bit ashamed:

walk/2:_I_want_walk/2_to_be_polymorphic,_i.e._to_apply_to_any_X_for
__%_which_speed/2_and_position/2_are_defined.
__walk(X,_NewX):-
_____speed(X,_S),
_____position(X,_P),
_____NewPosition_is_P_+_S,
____ setPosition(X, NewPosition, NewX).

But I seem to understand this is not common practice in prolog?

Maurizio

--
Best Regards,
Maurizio Colucci
Please remove the uppercase letters "S,P,A,M":
seSgPuAsMo.forever@tin.it
Nick Wedd

2004-04-20, 10:52 am

In message <RF8hc.109341$rM4.4304386@news4.tin.it>, seguso
<look@in.signature> writes
>Nick Wedd wrote:
>
>
>Thank you very much, but this is not what I wanted. I have ship/3 and
>plane/2 (ship and plane differ in number and meaning of the arguments), and
>I want to write walk/2 only once (you wrote two versions of walk/2), and it
>must work for both ship and plane. Finally, I want walk/2 to work for any
>term for which speed/2, position/2, and possibly something else, is
>defined.
>
>The solution I found was so easy I am a bit ashamed:
>
>walk/2:_I_want_walk/2_to_be_polymorphic,_i.e._to_apply_to_any_X_for
>__%_which_speed/2_and_position/2_are_defined.
>__walk(X,_NewX):-
>_____speed(X,_S),
>_____position(X,_P),
>_____NewPosition_is_P_+_S,
>____ setPosition(X, NewPosition, NewX).
>
>But I seem to understand this is not common practice in prolog?


I don't understand how this will work. Does setPosition/3 use retract
and assert?

Nick
--
Nick Wedd nick@maproom.co.uk
Nick Wedd

2004-04-20, 11:51 am

In message <rzYfkqn8JShAFAEO@maproom.demon.co.uk>, Nick Wedd
<nick@maproom.co.uk> writes

>
>I don't understand how this will work. Does setPosition/3 use retract
>and assert?


To clarify my lack of understanding:

You have a ship which is at position A, then it moves and it is at
position B. There are two ways you can achieve this. You can retract a
fact with A in it and assert a fact with B in it. Or you construct
something, with B in it, which is in an argument to your main loop.

I do not know which of these you are proposing.

Nick
--
Nick Wedd nick@maproom.co.uk
Bill Spight

2004-04-20, 11:51 am

Dear Maurizio,

Maurizio:
> % walk/2: I want walk/2 to be polymorphic, i.e. to apply to any X for
> % which speed/2 and position/2 are defined.
> walk(X, NewX):-
> speed(X, S),
> position(X, P),
> NewPosition is P + S,
> NewX = ????
>
>
> I need to call walk/2 both with X = ship(3,4,5) and with X = plane(3,4).
> What I need to say is "let NewX = a copy of X where the position has been
> replaced by NewPosition".
>
> Is there a way to do that?


Nick:

> You need to start by deciding what a ship looks like. Yours as above is
> ship( Width, Height, Passengers )
> with no position. I would prefer
> object( Type, Name, Position, Speed )
> Position and Speed have the form X/Y for a ship, X/Y/Z for a plane.
>

[snip]

> The properties of an object which change (position and speed) get
> carried around in your list, while the static properties are kept in
> facts like
> width( nancy, 20 ).
> height( nancy, 40 ).
> passengers( nacy, 300 ).
> nancy here is the ship's name, an atom, which no other object has.
>


Wise counsel! :-)

Maurizio:

> The solution I found was so easy I am a bit ashamed:
>
> walk/2: I want walk/2 to be polymorphic, i.e. to apply to any X for
> % which speed/2 and position/2 are defined.
> walk(X, NewX):-
> speed(X, S),
> position(X, P),
> NewPosition is P + S,
> setPosition(X, NewPosition, NewX).
>
> But I seem to understand this is not common practice in prolog?
>


Your solution is incomplete. We can't tell what you are doing, nor
whether it is common practice in Prolog or not.

Besides, I really can't say what is common practice in Prolog, anyway.
If you look at published material, you see a variety of styles and
approaches. However, I would not say that polymorphism is uncommon in
Prolog. It's certainly not difficult.

Good luck!

Bill
Lex Spoon

2004-04-20, 11:51 am

seguso <look@in.signature> writes:
> I need to call walk/2 both with X = ship(3,4,5) and with X = plane(3,4).
> What I need to say is "let NewX = a copy of X where the position has been
> replaced by NewPosition".



Easy -- have setPosition/3, just as you have polymorphic position/2.
Define setPosition for each kind of object you have.

setPosition(X, NewX, NewPosition)

The examples you are working on seem to fit Prolog *very* well.
Prolog is very happy to have varying implementations behind a
predicate. In fact, due to backtracking, it does it *better* than OO
languages: in an OO language, the first match wins, while in Prolog,
the system can change its mind later and try a different match.


Something that *won't* work well is modifying objects in place. You
can't literally change the position of X. You seem aware of that
limitation/strength already.

-Lex


seguso

2004-04-20, 1:40 pm

Nick Wedd wrote:

> walk(X,_NewX):-

No, it doesn't.
[color=darkred]
> To clarify my lack of understanding:
>
> You have a ship which is at position A, then it moves and it is at
> position B. __There_are_two_ways_you_can_achieve_thi
s.__You_can_retract_a
> fact with A in it and assert a fact with B in it.__Or_you_construct
> something, with B in it, which is in an argument to your main loop.
>
> I do not know which of these you are proposing.


Thanks again :-)

I mean

setPosition(ship(Size, Speed, _OldPos),
NewPos,
ship(Size, Speed, NewPos)).
setPosition(plane(Height, Passengers, Speed, _OldPos),
NewPos,
plane(Height, Passengers, Speed, NewPos)).

I hope this anwers Bill's post too.
--
Best Regards,
Maurizio Colucci
Please remove the uppercase letters "S,P,A,M":
seSgPuAsMo.forever@tin.it
seguso

2004-04-20, 1:40 pm

Lex Spoon wrote:

>
>
> Easy -- have setPosition/3, just as you have polymorphic position/2.
> Define setPosition for each kind of object you have.
>
> setPosition(X,_NewX,_NewPosition)



This is good news, since I was afraid this solution had some problem.

> The examples you are working on seem to fit Prolog very well.
> Prolog is very happy to have varying implementations behind a
> predicate. __In_fact,_due_to_backtracking,_it_does_
it_better_than_OO
> languages: in an OO language, the first match wins, while in Prolog,
> the system can change its mind later and try a different match.
>
>
> Something that won't work well is modifying objects in place.__You
> can't literally change the position of X.__You_seem_aware_of_that
> limitation/strength already.


This is a strength IMO :-)

Thank you!

--
Best Regards,
Maurizio Colucci
Please remove the uppercase letters "S,P,A,M":
seSgPuAsMo.forever@tin.it
seguso

2004-04-20, 1:40 pm

Lex Spoon wrote:

>
> The examples you are working on seem to fit Prolog very well.
> Prolog is very happy to have varying implementations behind a
> predicate. __In_fact,_due_to_backtracking,_it_does_
it_better_than_OO
> languages: in an OO language, the first match wins, while in Prolog,
> the system can change its mind later and try a different match.
>


This is fantastic, I hadn't realized.

+5, Insightful. :-)
--
Best Regards,
Maurizio Colucci
Please remove the uppercase letters "S,P,A,M":
seSgPuAsMo.forever@tin.it
seguso

2004-04-20, 1:40 pm

Bill Spight wrote:

>
> Your solution is incomplete. We can't tell what you are doing, nor
> whether it is common practice in Prolog or not.


Ok, then it isn't common practice :-))) Otherwise it would have been
obvious.

Thanks!

--
Best Regards,
Maurizio Colucci
Please remove the uppercase letters "S,P,A,M":
seSgPuAsMo.forever@tin.it
Paulo Moura

2004-04-21, 8:38 pm

Lex Spoon <lex@cc.gatech.edu> wrote in message news:<m3fzayu19b.fsf@logrus.dnsalias.net>...
> seguso <look@in.signature> writes:
>
>
> Easy -- have setPosition/3, just as you have polymorphic position/2.
> Define setPosition for each kind of object you have.
>
> setPosition(X, NewX, NewPosition)
>
> The examples you are working on seem to fit Prolog *very* well.
> Prolog is very happy to have varying implementations behind a
> predicate. In fact, due to backtracking, it does it *better* than OO
> languages: in an OO language, the first match wins, while in Prolog,
> the system can change its mind later and try a different match.


Unless you're using an object-oriented extension to Prolog such as
Logtalk (http://www.logtalk.org/), in which case you can have your
cake and eat it too :-)

Cheers,

Paulo
Lex Spoon

2004-04-23, 1:38 pm

pmoura@di.ubi.pt (Paulo Moura) writes:

> Lex Spoon <lex@cc.gatech.edu> wrote in message news:<m3fzayu19b.fsf@logrus.dnsalias.net>...
>
> Unless you're using an object-oriented extension to Prolog such as
> Logtalk (http://www.logtalk.org/), in which case you can have your
> cake and eat it too :-)
>



For the really curious (or sick, I don't know which), someone added a
few primitives to Smalltalk so that it could do Prolog-style
backtracking. No unification, however.

http://portal.acm.org/citation.cfm?...ACM&coll=portal


Also, Brian MacNamara has a more thorough Prolog extension of C++,
called LC++. I dunno if it is published yet, but it should be
floating around soon.

It's a crazy world.

-Lex

Sponsored Links







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

Copyright 2008 codecomments.com