Version française
Home     About     Download     Resources     Contact us    
Browse thread
Functional design for a basic simulation pipe.
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Hugo Ferreira <hmf@i...>
Subject: Re: [Caml-list] Functional design for a basic simulation pipe.
Hi,

Pietro Abate wrote:
> Hi,
> 
> On Wed, Oct 10, 2007 at 11:56:02AM +0100, Hugo Ferreira wrote:
>>>> a: requires the input of a state and outputs an event
>>>> b: requires input of a state and the event generated at that state and
>>>> outputs processed data
>>>> c: consumes n number elements of processed data and stops when it
>>>> requires no more such data
>>>>
>>>> Note that "c" will "pull in" for example 10 states and check for
>>>> termination, "b" will therefore need "pull in" 10 events. Each time it
>>>> pulls in an event it generates a state. This last state must be made
>>>> available to "a" so that it may generate its next event.
>>>>
>>>> The issue here is how can I implement this so that I can flexibly
>>>> configure experiments by "constructing" a chain of actions but still be
>>>> able to pass back the state to one of those actions. Something like:
>>>>
>>>> let exp = a |> b (output 1 back to a) |> c
> I'm not entirely sure this is correct. Note that I've used an exception
> to get out of the loop just because I'm too lazy to wrap my head around
> the exception monad. I'm also not sure that is the best way of using a
> state monad... Any monad-experts out there to comment ?
> 

I am going to have to look at this very carefully (read: learn something
about monads). Comment below.

> This is the code:
> 
> type inputstate = int
> type output = int
> type final = int
> type event = int
> 
> module StateMonadMake(T:sig type t end) =
> struct
>   type 'state mt = 'state -> T.t * 'state
> 
>   let return a = fun s -> a, s
>   let bind m f = fun s -> let a, s = m s in f a s
>   let fetch = fun s -> return s s
>   let store = fun s -> fun _ -> return () s
>   let modify f = fun s -> return () (f s)
> end
> 
> module SM = StateMonadMake(struct type t = inputstate end)
> exception Stop of final
> 
> let a (s : inputstate) : event = 1
> 
> let b (e : event) ( s : inputstate ) : (inputstate * output) =
>     match s with
>     0 -> print_endline "final state" ; (0,1)
>     |_ -> Printf.printf "at state %i\n" s ; (s-1,s+1)
> 
> let c ( l : output list ) : final =
>     List.iter print_int l ;
>     List.fold_left (+) 0 l
> 
> let rec exp inputstate =
>     SM.bind inputstate (fun state ->
>         let newevent = a state in
>         let (newstate,newdata) = b newevent state in
>         SM.bind (SM.modify (fun olddata -> newdata::olddata)) (fun _ ->
>             if newstate = 0 then
>                 SM.bind (SM.fetch) (fun data ->
>                     raise ( Stop ( c (data) ))
>                 )
>             else exp (SM.return newstate)
>         )
>     )
> ;;
> 

I can however see that "exp" seems to be a loop. Cannot see however were
you tie the latest state of "a" with the next use of "b" 8-(. I will
really have to see how this stuff works.

Thanks.

Hugo F.

> let run =
>     try exp (SM.return 10) []
>     with Stop(i) -> Printf.printf "final %i\n" i
> 
> $ocaml hf.ml 
> at state 10
> at state 9
> at state 8
> at state 7
> at state 6
> at state 5
> at state 4
> at state 3
> at state 2
> at state 1
> 234567891011final 65
> 
> 
> pietro
> 
>>> Just to be sure I understood well, here is a diagram:
>>>
>>> --> a --> b -+-------------------------------------------------> output1
>>>              |
>>>              +--state1-> a --> b -+----------------------------> output2
>>>                                   |
>>>                                   +-state2-> a --> b -+--------> output3
>>>                                                       |
>>>                                                          ...
>>>                                                               -> outputn
>>>
>>>                                                                     |
>>>                                                                     |
>>>                                                                     |
>>>                                                                     V
>>>
>>>                                                                     c
>>>
>>>
>>> Do you agree with this ? (n beeing a variable of course...)
>> Not quite. More like:
>>
>> (_,s0)
>> -> a-> s0,e1 -> b -+--------------------------------------> s1
>>                    |
>>                    +--s1-> a -> s1,e2 -> b-+--------------> s2
>>                                            |
>>                                             ...
>>                                                          -> sn
>>                                                             |
>>                                                             |
>>                                                             |
>>                                                             V
>>                                                             c
>>
>> Note that "a" doesn't generates states "sn" it just passes it on.
>> It only generates events "en". "b" simple takes a state "sn-1" and the
>> events "en" and generates a new state "sn".
>>
>>> Shall c also take the states ?
>>>
>> Yes. But the idea is to add other functions to the "pipe" that will
>> change states to other data types for further processing.
>>
>> Note also that only the last function actually knows how much data is
>> required.
>>
>>> (I believe in good drawings to help finding an answer...)
>> Well it certainly easier to express the flow of the data.
>>
>>
>>
>>> _______________________________________________
>>> Caml-list mailing list. Subscription management:
>>> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
>>> Archives: http://caml.inria.fr
>>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>>>
>>>
>> _______________________________________________
>> Caml-list mailing list. Subscription management:
>> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
>> Archives: http://caml.inria.fr
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>