From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p37GnAkl005190 for ; Thu, 7 Apr 2011 18:49:10 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkACAO7pnU1KfVI0kGdsb2JhbACESqE2CBQBAQEBCQkNBxQEIaVUiiw8giOFGTGIXQEBAwaEb3gEjUWJMzo X-IronPort-AV: E=Sophos;i="4.63,317,1299452400"; d="scan'208";a="96514246" Received: from mail-ww0-f52.google.com ([74.125.82.52]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 07 Apr 2011 18:49:05 +0200 Received: by wwe15 with SMTP id 15so3979645wwe.9 for ; Thu, 07 Apr 2011 09:49:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:from:date:message-id:subject:to :content-type; bh=tkpr65nub7o5PuZE2Gc09Lh+qNnsPnkqXSk7l6sJELY=; b=eLaWZ5kbJx1AcWdPcnqa8hfa7FxDL1MiI9wwIUabnDMboq94NUni0hPLwRTZaVsl4z 5UE4pBlL3/4hJQGtEMsqdwM7wiD/CgHni/2trh7WYrMb5KXWwQ0nEAZjREd0/n3OEQlm cbR6HpneuPP4Ey1oPZsnQjZhBuIZOj/JO1Lq0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:content-type; b=KRZymUSF6L5ssig73aAnjqUizTNVRq72Y9Cmqx5xHLDdGfvxtDC8LfsXu8qWO9kGH+ PWENLgFBWTlBHxqIUp0m1fHoGkzqofird1kY/Hq722SdkwKYzsLjLkmcDm9riY8TGgeR tmH0bgB8+T4py75LYHy3PfFr8W5HkxU5SZipw= Received: by 10.227.208.73 with SMTP id gb9mr1172190wbb.194.1302194945152; Thu, 07 Apr 2011 09:49:05 -0700 (PDT) MIME-Version: 1.0 Received: by 10.216.18.139 with HTTP; Thu, 7 Apr 2011 09:48:45 -0700 (PDT) From: Pierre-Alexandre Voye Date: Thu, 7 Apr 2011 18:48:45 +0200 Message-ID: To: caml-list Content-Type: multipart/alternative; boundary=00151748e7c22259c904a056e39d Subject: [Caml-list] Trouble with subtyping --00151748e7c22259c904a056e39d Content-Type: text/plain; charset=UTF-8 Hi all, I'm working on a lib to modelize a Multi-Agent System where each agent are driven by a Hierarchical Finite State Machine (HFSM). Hierarchical means that each state could contain a HFSM which is runned when the machine come into the state. Transitions are made by evaluating condition and events which arrives in a mail inbox. The goal is to define dynamically all HFSM we want, just by defining states and transitions This little grammar represents all possibilities of mix of condition and event handling type ('myAgentType, 'event) transition = Condition of ('myAgentType -> bool) | Event of ('event -> bool) | EventOr of ('event -> bool) * ('myAgentType,'event) transition | EventAnd of ('event -> bool) * ('myAgentType,'event) transition | EventXor of ('event -> bool) * ('myAgentType,'event) transition | EventNot of ('event -> bool) | ConditionOr of ('myAgentType -> bool) * ('myAgentType,'event) transition | ConditionAnd of ('myAgentType -> bool) * ('myAgentType,'event) transition | ConditionXor of ('myAgentType -> bool) * ('myAgentType,'event) transition | ConditionNot of ('myAgentType -> bool);; I have two classes : agent and state "state" manage current state and is able to search, according to the agent given in argument, what is the following state. So state have a transition list which is (state * ('myAgentType, 'event) transition ) list (see before). in this list, state is the (candidate) next state, and ('myAgentType, 'event) transition the expression which allows to validate or not the transition. 'event will always be the same object, but I want 'myAgentType to be every object which inherit from agent. The agent have a current state, and a 'cycle' method which searchs what is the next state of the agent according to its (the current state) transition list You use it like it : let mydwarf = new agent;; let (ctdwarf:(dwarf,masEvent) transition) = Condition (fun (e:agent) -> true);; let aa = new state mydwarf;; let aaa = new state mydwarf;; aaa#setParent aa;; let aab = new state mydwarf;; aab#isIn aa;; aaa#addTransition aab (Condition (fun (e:agent) -> true));; mydwarf#setStartState aa;; So we have defined an agent mydwarf which have a start state "aa" here a simplified prototype of agent and state class : class ['myAgentType] state : 'myAgentType -> object constraint 'myAgentType = < getCurrentState : < getNom : string; .. > ... >; val mutable action : 'myAgentType -> unit val mutable begin_action : 'myAgentType -> unit val mutable end_action : 'myAgentType -> unit val mutable transitions : ('myAgentType state option * ('myAgentType, masEvent) transition option) list method searchTransition : 'myAgentType -> bool * 'myAgentType state * 'myAgentType state * 'myAgentType state * 'myAgentType state method has : 'myAgentType state -> unit method isTransitionValide : bool method setAction : ('myAgentType -> unit) -> unit method setBeginAction : ('myAgentType -> unit) -> unit method setEndAction : ('myAgentType -> unit) -> unit method setTransitions : ('myAgentType state option * ('myAgentType, masEvent) transition option) list -> unit end class agent : object val mutable birthtime : int val mutable currentState : agent state option val mutable gid : int val mutable id : int val mutable emailStack : masEvent option list val mutable pv : int val mutable state_time : int method cycle : agent -> unit method getCurrentState : agent state method setStartState : agent state -> unit method setState : agent state -> agent state -> agent state -> agent -> unit end Now, all the logic works fine. My big problem, is I'm unable to make it working with a class which inherit from agent. I'm forced to copy all the code for each type of agent I want. For instance, if i define : class inheritedDwarf = object (self) inherit agent val mutable currentState = ( None : inheritedDwarf state option) end;; it works. But if I define : class inheritedDwarf = object (self) inherit agent val mutable currentState = ( None : inheritedDwarf state option) val specialValue=0 method getSpecialValue = specialValue end;; From the toplevel I get : Error: The abbreviation inheritedDwarf expands to type < cycle : dwarf -> unit; getCurrentState : dwarf state; getMail : masEvent -> unit; getPileEmail : masEvent option list; getPv : int; getSpecialValue : int; receiveEMail : masEvent option -> unit; removeOldEmail : unit; setPileEmail : masEvent option list -> unit; setPv : int -> unit; setStartState : dwarf state -> unit; setState : dwarf state -> dwarf state -> dwarf state -> dwarf -> unit > but is used with type < cycle : dwarf -> unit; getCurrentState : dwarf state; getMail : masEvent -> unit; getPileEmail : masEvent option list; getPv : int; receiveEMail : masEvent option -> unit; removeOldEmail : unit; setPileEmail : masEvent option list -> unit; setPv : int -> unit; setStartState : dwarf state -> unit; setState : dwarf state -> dwarf state -> dwarf state -> dwarf -> unit > So, it doesn't want to accept currentState to become a inheritedDwarf state option and thus, I can't use my inheritedDwarf Is there a solution ? Thans for your help, Regards, Pierre-Alexandre -- --------------------- Isaac Project - http://www.lisaac.org/ --00151748e7c22259c904a056e39d Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi all, I'm working on a lib to modelize a Multi-Agent System where eac= h agent are driven by a Hierarchical Finite State Machine (HFSM). Hierarchi= cal means that each state could contain a HFSM which is runned when the mac= hine come into the state.

Transitions are made by evaluating condition and events which arrives i= n a mail inbox.
The goal is to define dynamically all HFSM we want, just= by defining states and transitions

This little grammar represents a= ll possibilities of mix of condition and event handling
type ('myAgentType, 'event) transition =3D
=C2=A0=C2=A0 Conditi= on of ('myAgentType -> bool)
=C2=A0 | Event=C2=A0=C2=A0=C2=A0=C2= =A0 of ('event=C2=A0 -> bool)
=C2=A0 | EventOr=C2=A0=C2=A0 of (&= #39;event -> bool) * ('myAgentType,'event) transition
=C2=A0 | EventAnd=C2=A0 of ('event -> bool) * ('myAgentType,'= ;event) transition
=C2=A0 | EventXor=C2=A0 of ('event -> bool) * = ('myAgentType,'event) transition
=C2=A0 | EventNot=C2=A0 of (= 9;event -> bool)
=C2=A0 | ConditionOr=C2=A0 of ('myAgentType -&g= t; bool) * ('myAgentType,'event) transition
=C2=A0 | ConditionAnd of ('myAgentType -> bool) * ('myAgentType,= 'event) transition
=C2=A0 | ConditionXor of ('myAgentType -> = bool) * ('myAgentType,'event) transition
=C2=A0 | ConditionNot o= f ('myAgentType -> bool);;

I have two classes : agent and state
"state" manage curren= t state and is able to search, according to the agent given in argument, wh= at is the following state.
So state have a transition list which is (sta= te * ('myAgentType, 'event) transition ) list (see before).
in this list, state is the (candidate) next state, and=C2=A0 ('myAgentT= ype, 'event) transition the expression which allows to validate or not = the transition.
'event will always be the same object, but I want &#= 39;myAgentType to be every object which inherit from agent.


The agent have a current state, and a 'cycle' method which = searchs what is the next state of the agent according to its (the current s= tate) transition list

You use it like it :
let mydwarf =3D new ag= ent;;
let (ctdwarf:(dwarf,masEvent) transition) =3D Condition (fun (e:agent) ->= ; true);;

let aa =3D new state mydwarf;;
let aaa =3D new state my= dwarf;;
aaa#setParent aa;;

let aab =3D new state=C2=A0 mydwarf;;<= br>aab#isIn aa;;

aaa#addTransition aab (Condition (fun (e:agent) -> true));;

m= ydwarf#setStartState aa;;

So we have defined an agent mydwarf which = have a start state "aa"




here a simplified prot= otype of agent and state class :
class ['myAgentType] state :
=C2=A0 'myAgentType ->
=C2=A0= object
=C2=A0=C2=A0=C2=A0 constraint 'myAgentType =3D
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 < getCurrentState : < getNom : string; .. >= =C2=A0 ... >;
=C2=A0=C2=A0=C2=A0 val mutable action : 'myAgentTy= pe -> unit
=C2=A0=C2=A0=C2=A0 val mutable begin_action : 'myAgentType -> unit=C2=A0=C2=A0=C2=A0 val mutable end_action : 'myAgentType -> unit=C2=A0
=C2=A0=C2=A0=C2=A0 val mutable transitions :
=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 ('myAgentType state option * ('myAgentType, masE= vent) transition option) list

=C2=A0=C2=A0=C2=A0 method searchTransition :
=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 'myAgentType -> bool * 'myAgentType state * 'myAge= ntType state * 'myAgentType state * 'myAgentType state
=C2=A0=C2= =A0
=C2=A0=C2=A0=C2=A0 method has : 'myAgentType state -> unit =C2=A0=C2=A0=C2=A0 method isTransitionValide : bool
=C2=A0=C2=A0=C2=A0 m= ethod setAction : ('myAgentType -> unit) -> unit
=C2=A0=C2=A0= =C2=A0 method setBeginAction : ('myAgentType -> unit) -> unit
= =C2=A0=C2=A0=C2=A0 method setEndAction : ('myAgentType -> unit) ->= ; unit
=C2=A0=C2=A0=C2=A0 method setTransitions :
=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 ('myAgentType state option * ('myAgentType, masEvent) transitio= n option) list -> unit
=C2=A0 end


class agent :
=C2=A0 = object
=C2=A0=C2=A0=C2=A0 val mutable birthtime : int
=C2=A0=C2=A0=C2= =A0 val mutable currentState : agent state option
=C2=A0=C2=A0=C2=A0 val mutable gid : int
=C2=A0=C2=A0=C2=A0 val mutable = id : int
=C2=A0=C2=A0=C2=A0 val mutable emailStack : masEvent option lis= t
=C2=A0=C2=A0=C2=A0 val mutable pv : int
=C2=A0=C2=A0=C2=A0 val muta= ble state_time : int
=C2=A0=C2=A0=C2=A0 method cycle : agent -> unit<= br>=C2=A0=C2=A0=C2=A0 method getCurrentState : agent state
=C2=A0=C2=A0=C2=A0 method setStartState : agent state -> unit
=C2=A0= =C2=A0=C2=A0 method setState : agent state -> agent state -> agent st= ate -> agent -> unit
=C2=A0 end



Now, all the logic = works fine.


My big problem, is I'm unable to make it working= with a class which inherit from agent. I'm forced to copy all the code= for each type of agent I want.

For instance, if i define :
class inheritedDwarf =3D object (self)=C2=A0 inherit agent
=C2=A0 val mutable currentState =3D ( None : inhe= ritedDwarf state option)
=C2=A0
end;;=C2=A0=C2=A0=C2=A0

it wo= rks.

But if I define :

class inheritedDwarf =3D object (self)
=C2=A0 inherit agent
=C2= =A0 val mutable currentState =3D ( None : inheritedDwarf state option)
= =C2=A0
=C2=A0 val specialValue=3D0
=C2=A0 method getSpecialValue =3D = specialValue
end;;

=C2=A0From the toplevel I get :
Error: The abbreviation inheritedDwarf expands to type
=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 < cycle : dwarf -> unit; getCurrentState : dwar= f state;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 getMail : masE= vent -> unit; getPileEmail : masEvent option list;
=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 getPv : int; getSpecialValue : int;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 receiveEMail : masEvent op= tion -> unit; removeOldEmail : unit;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 setPileEmail : masEvent option list -> unit; setPv : = int -> unit;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 setStar= tState : dwarf state -> unit;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 setState : dwarf state -> dwarf state -> dwarf state -> = dwarf -> unit >
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 but is used with type
=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 < cycle : dwarf -> unit; getCurrentState : d= warf state;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 getMail : m= asEvent -> unit; getPileEmail : masEvent option list;
=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 getPv : int; receiveEMail : masEvent opti= on -> unit;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 removeOldEmail : unit; set= PileEmail : masEvent option list -> unit;
=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 setPv : int -> unit; setStartState : dwarf state -= > unit;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 setState : d= warf state -> dwarf state -> dwarf state -> dwarf -> unit ><= br>




So, it doesn't want to accept currentState to becom= e a inheritedDwarf state option and thus, I can't use my inheritedDwarf=

Is there a solution ?

Thans for your help,

Regards,
Pierre-Alexandre

--
---------------------
I= saac Project - http://www.lisaac.org/
--00151748e7c22259c904a056e39d--