caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Pietro Abate <Pietro.Abate@anu.edu.au>
To: ocaml ml <caml-list@inria.fr>
Subject: [Caml-list] sharing problem ...
Date: Mon, 26 Jan 2004 21:43:45 +1100	[thread overview]
Message-ID: <20040126104345.GA3978@pulp.anu.edu.au> (raw)

[-- Attachment #1: Type: text/plain, Size: 1652 bytes --]

Hi all,
I'm trying to implement a (string * set) hashtbl
where some element (set) should be shared between different
objects.
the main point is that when I clone an object I want to duplicate
some sets and shared others (sticky sets)

I tried to achieve this result with the method below.
it use the set_copy to duplicate a set and does nothing when then 
element is marked as "shared".

        method copy =
            let set_copy s =
                MySet.fold (
                    fun e s ->
                        MySet.add e s
                ) MySet.empty s
            in
            let map_copy m =
                MyMap.fold (
                    fun k (s,t) m ->
                        (* this one should be the same set *)
                        if t then MyMap.add k (s,t) m
                        (* this one should be a copy !! *)
                        else MyMap.add k (set_copy(s),t) m
                ) MyMap.empty m
        in {< sets = map_copy sets >}

Of course this is not the right way of doing it as the map with key "a"
(in the small example attached) is not shared at all...
this is the result I'd like to get:

a1: 
a(shared) : [1;2;3;]
b:[1;2;3;]

a2: 
a(shared) : [1;2;3;4;5;]
b:[1;2;3;4;5;]

a1: 
a(shared) : [1;2;3;4;5]            <---------------here !!!
b:[1;2;3;]


how can I efficiently share elements in this kind of structure ?

p

-- 
++ Our capacity for understanding is inversely proportional to 
   how much we think we know. The more I know, the more I know 
   I don't know...
++ Please avoid sending me Word or PowerPoint attachments.
   See http://www.fsf.org/philosophy/no-word-attachments.html

[-- Attachment #2: htest.ml --]
[-- Type: text/plain, Size: 2409 bytes --]



module MyMap = Map.Make(
    struct
        type t = string
        let compare = compare 
    end)

module MySet = Set.Make(
    struct
        type t = int
        let compare = compare
    end)


class mystruct l =
    object(self)
        initializer List.iter (fun (h,s) -> self#add_name ~t:s h ) l
        
        val mutable sets = MyMap.empty

        method add_name ?(t=false) name=
            if not(MyMap.mem name sets) then
                sets <- MyMap.add name (MySet.empty,t) sets
            else ()
        
        method clone = {< sets = sets >}

        method copy =
            let set_copy s =
                MySet.fold (
                    fun e s ->
                        MySet.add e s
                ) MySet.empty s
            in
            let map_copy m =
                MyMap.fold (
                    fun k (s,t) m ->
                        if t then MyMap.add k (s,t) m
                        else MyMap.add k (set_copy(s),t) m
                ) MyMap.empty m
        in {< sets = map_copy sets >}

        method add_elem name tl =
            try
                let (set,t) = MyMap.find name sets in
                let set' =
                    List.fold_left (
                        fun s t -> MySet.add t s
                    ) set tl
                in
                sets <- MyMap.remove name sets;
                sets <- MyMap.add name (set',t) sets
            with Not_found ->
                Printf.printf "%s : " name;
                failwith "My not declared"

        method print =
            MyMap.iter (
                fun k (s,t) ->
                    print_string k ;
                    if t then print_string "(shared) : "
                    else  print_string ":";
                    print_string "[";
                    MySet.iter (
                        fun e ->
                            print_int e; 
                            print_string ";"
                    ) s;
                print_endline "]"
            ) sets

end

let a1 = new mystruct ["a",true;"b",false] ;;

let _ =
    a1#add_elem "a" [1;2;3];
    a1#add_elem "b" [1;2;3];
    print_endline "a1: ";
    a1#print;
    print_newline ();;

let a2 = a1#copy;;

let _ =
    a2#add_elem "a" [4;5];
    a2#add_elem "b" [4;5];
    print_endline "a2: ";
    a2#print;
    print_newline ();
    print_endline "a1: ";
    a1#print;
    print_newline ();;



             reply	other threads:[~2004-01-26 10:40 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-26 10:43 Pietro Abate [this message]
2004-01-26 11:22 ` Nicolas Cannasse
2004-01-26 13:27 ` Damien Doligez
2004-01-26 13:46   ` Pietro Abate

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040126104345.GA3978@pulp.anu.edu.au \
    --to=pietro.abate@anu.edu.au \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).