Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] help
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Matt Gushee <mgushee@h...>
Subject: Re: [Caml-list] help
On Sun, Apr 25, 2004 at 01:53:48AM +0000, mohammad siddiqui wrote:
> Hello,
> 
> I am having problem dealing with data structures in OCAML, I am translating 
> code from C to OCAML. As shown below one structure contains array of other 
> structures as its field. One of the guys here told me that we can?t 
> ?inline? structures into other structures in OCAML.
> I don?t how to deal with this, I already spent like 2 days on it. Should I 
> make use of objects and let some member of it array of other objects? I am 
> not sure this will do the purpose. I really appreciate if anyone helps me 
> out this.
> 
> For example if try to change the value model.supvec. (1).words. (1).wnum, 
> it changes the values of all elements of the array model.supvec. I tried 
> using references, mutable fields, Array.set function for modifying the 
> contents of individual element.
> 
> The structures in OCAML are:
> 
> type word = { mutable wnum:int;	       (* word number *)
> 	     mutable weight:float };;	       (* word weight *)
> 
> type doc =  {
> 	      mutable docnum:int;              (* Document ID *)
> 	      mutable   queryid:
> 	      mutable costfactor:float;
> 	      mutable  twonorm_sq:float;
> 	      mutable   words:word array
> 	     };;
> 
> type model =         {
>                        mutable   sv_num:int;
>                        mutable  at_upper_bound:int;
>                        mutable  b:float;
>                        mutable  supvec:doc array;
> 			 mutable alpha: int array;
> 
>                       } ;;
> 
> The Structures in C are
> 
> typedef struct word {
> int wnum;
> float weight;
> } WORD;
> 
> typedef struct doc {
>  long    docnum;
>  long    queryid;
>  double  costfactor;
>  double  twonorm_sq;
>  WORD    *words;
> } DOC;
> 
> 
> 
> typedef struct model {
>  long    sv_num;
>  long    at_upper_bound;
>  double   b;
>  DOC     **supvec;
>  Double  *alpha;
> } MODEL;
> 
> _________________________________________________________________
> FREE pop-up blocking with the new MSN Toolbar ? get it now! 
> http://toolbar.msn.com/go/onm00200415ave/direct/01/
> 
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives: 
> http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: 
> http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners

On Sun, Apr 25, 2004 at 04:30:56PM +0000, mohammad siddiqui wrote:

> I tried exactly what you have told. Its is fine when we just have one 
> element in an array of words. If we have more than one, changing the value 
> of one changes the values of the rest of the elements.

That's not exactly what's happening, though your example makes it look
that way.

> for example , if the test_model is initialiazed like this:
> 
> let test_model =
> { sv_num=0; at_upper_bound=0; b=0.; supvec=Array.make 2
> { docnum=0; queryid=0; costfactor=0.; twonorm_sq=0.; words=Array.make 1
> { wnum=ref 0; weight=0. } }; alpha=0. };

Okay, we can see the cause of the problem here: you are initializing an
array with Array.make, where the initial value includes a ref. The
resulting array will have unique members, *except* that each 'wnum'
field points to a single, shared ref value. That's the problem.


> now if i change the values , it chnages all th elements of the array 
> "supvec" in model
> 
> test_model.supvec.(0).words.(0).wnum := 1;

As you probably understand by now, what this is really doing is changing
all instances of the shared value stored in the 'wnum' field. Evidently 
that was the only field you tried to change, in which case it would
appear that all the elements of 'supvec' were being changed.

Here are three possible solutions:

  1. Make wnum a mutable field instead of a ref.

  2. Replace the array member instead of setting the ref:

       test_model.supvec.(0).words <- newvalue

     (but then I guess there's no point in 'wnum' being either a ref or
      a mutable field)

  3. Don't use Array.make to initialize the array. Instead, use a 
     recursive function that starts with an empty array, and adds new
     elements with Array.append.

-- 
Matt Gushee                 When a nation follows the Way,
Englewood, Colorado, USA    Horses bear manure through
mgushee@havenrock.com           its fields;
http://www.havenrock.com/   When a nation ignores the Way,
                            Horses bear soldiers through
                                its streets.
                                
                            --Lao Tzu (Peter Merel, trans.)

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners