1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/Tools/isac/Frontend/states.sml Wed Aug 25 16:20:07 2010 +0200
1.3 @@ -0,0 +1,487 @@
1.4 +(* states for calculation in global refs
1.5 + use"../states.sml";
1.6 + use"states.sml";
1.7 + *)
1.8 +
1.9 +(*
1.10 +type hide = (pblID *
1.11 + string list * (*hide: tacs +
1.12 + "ALL", .. result immediately
1.13 + "MODELPBL", .. modeling hidden
1.14 + "SPEC", .. specifying hidden
1.15 + "MODELMET", .. (additional itms !)
1.16 + "APPLY", .. solving hidden
1.17 + detail: rls
1.18 + "Rewrite_*" (as strings) must _not_ be ..
1.19 + .. contained in this list, rls _only_ !*)
1.20 + bool) (*inherit to children in pbl-herarchy*)
1.21 + list;
1.22 +
1.23 +(*. points a pbl/metID to a sub-hierarchy of key ?.*)
1.24 +fun is_child_of child key =
1.25 + let fun is_ch [] [] = true (*is child of itself*)
1.26 + | is_ch (c::_) [] = true
1.27 + | is_ch [] (k::_) = false
1.28 + | is_ch (c::cs) (k::ks) =
1.29 + if c = k then is_ch cs ks else false
1.30 + in is_ch (rev child) (rev key) end;
1.31 +(*
1.32 +is_child_of ["root","univar","equation"] ["univar","equation"];
1.33 +val it = true : bool
1.34 +is_child_of ["root","univar","equation"] ["system","equation"];
1.35 +val it = false : bool
1.36 +is_child_of ["equation"] ["system","equation"];
1.37 +val it = false : bool
1.38 +is_child_of ["root","univar","equation"] ["linear","univar","equation"];
1.39 +val it = false : bool
1.40 +*)
1.41 +
1.42 +(*.what tactics have to be hidden (in model/specify these may be several).*)
1.43 +datatype hid =
1.44 + Show (**)
1.45 + | Hundef (**)
1.46 + | Htac (*a tactic has to be hidden*)
1.47 + | Hmodel (*the model of the (sub)problem has to be hidden*)
1.48 + | Hspecify (*the specification of the (sub)problem has to be hidden*)
1.49 + | Happly; (*solving the (sub)problem has to be hidden*)
1.50 +
1.51 +(*. search all pbls if there is some tactic or model/spec/calc to hide .*)
1.52 +fun is_hid pblID arg [] = Show
1.53 + | is_hid pblID arg ((pblID', strs, inherit)::pts) =
1.54 + let fun is_mem arg =
1.55 + if arg mem strs then Htac
1.56 + else if arg mem ["Add_Given","Add_Find","Add_Relation"]
1.57 + andalso "MODEL" mem strs then Hmodel
1.58 + else if arg mem ["Specify_Theory","Specify_Problem",
1.59 + "Specify_Method"]
1.60 + andalso "SPEC" mem strs then Hspecify
1.61 + else if "APPLY" mem strs then Htac
1.62 + else Hundef
1.63 + in if inherit then
1.64 + if is_child_of (pblID:pblID) pblID'
1.65 + then case is_mem arg of Hundef => is_hid pblID arg (pts:hide)
1.66 + | hid => hid
1.67 + else is_hid pblID arg pts
1.68 + else if pblID = pblID'
1.69 + then case is_mem arg of Hundef => is_hid pblID arg (pts:hide)
1.70 + | hid => hid
1.71 + else is_hid pblID arg pts
1.72 + end;
1.73 +(*val hide = [([],["Refine_Tacitly"],true),
1.74 + (["univar","equation"],["Apply_Method","Model_Problem","SPEC"],
1.75 + false)]
1.76 + :hide;
1.77 +is_hid [] "Rewrite" hide;
1.78 +val it = Show
1.79 +is_hid ["any","problem"] "Refine_Tacitly" hide;
1.80 +val it = Htac
1.81 +is_hid ["root","univar","equation"] "Apply_Method" hide;
1.82 +val it = Show
1.83 +is_hid ["univar","equation"] "Apply_Method" hide;
1.84 +val it = Htac
1.85 +is_hid ["univar","equation"] "Specify_Problem" hide;
1.86 +val it = Hspecify
1.87 +*)
1.88 +
1.89 +fun is_hide pblID (tac as (Subproblem (_,pI))) (det:detail) =
1.90 + is_hid pblID "SELF" det
1.91 + | is_hide pblID (tac as (Rewrite (thmID,_))) det =
1.92 + is_hid pblID thmID det
1.93 + | is_hide pblID (tac as (Rewrite_Inst (_,(thmID,_)))) det =
1.94 + is_hid pblID thmID det
1.95 + | is_hide pblID (tac as (Rewrite_Set rls)) det =
1.96 + is_hid pblID rls det
1.97 + | is_hide pblID (tac as (Rewrite_Set_Inst (_,rls))) det =
1.98 + is_hid pblID rls det
1.99 + | is_hide pblID tac det = is_hid pblID (tac2IDstr tac) det;
1.100 +(*val hide = [([],["Refine_Tacitly"],true),
1.101 + (["univar","equation"],["Apply_Method","Model_Problem",
1.102 + "SPEC","SELF"],
1.103 + false)]
1.104 + :hide;
1.105 +is_hide [] (Rewrite ("","")) hide;
1.106 +val it = Show
1.107 +is_hide ["any","problem"] (Refine_Tacitly []) hide;
1.108 +val it = Htac
1.109 +is_hide ["root","univar","equation"] (Apply_Method []) hide;
1.110 +val it = Show
1.111 +is_hide ["univar","equation"] (Apply_Method []) hide;
1.112 +val it = Htac
1.113 +is_hide ["univar","equation"] (Specify_Problem []) hide;
1.114 +val it = Hspecify
1.115 +is_hide ["univar","equation"] (Subproblem (e_domID,["univar","equation"]))hide;
1.116 +val it = Htac
1.117 +is_hide ["equation"] (Subproblem (e_domID,["univar","equation"]))hide;
1.118 +val it = Show
1.119 +*)
1.120 +
1.121 +
1.122 +(*. search all pbls in detail if there is some rls' to be detailed .*)
1.123 +fun is_det pblID arg [] = false
1.124 + | is_det pblID arg ((pblID', rlss, inherit)::pts) =
1.125 + if inherit then
1.126 + if is_child_of (pblID:pblID) pblID'
1.127 + then if arg mem rlss then true
1.128 + else is_det pblID arg (pts:detail)
1.129 + else is_det pblID arg pts
1.130 + else if pblID = pblID'
1.131 + then if arg mem rlss then true
1.132 + else is_det pblID arg (pts:detail)
1.133 + else is_det pblID arg pts;
1.134 +
1.135 +(*fun is_detail pblID (tac as (Subproblem (_,pI))) (det:detail) =
1.136 + is_det pblID "SELF" det*)
1.137 +fun is_detail pblID (tac as (Rewrite_Set rls)) det =
1.138 + is_det pblID rls det
1.139 + | is_detail pblID (tac as (Rewrite_Set_Inst (_,rls))) det =
1.140 + is_det pblID rls det
1.141 + | is_detail _ _ _ = false;
1.142 +----------------------------------------*)
1.143 +
1.144 +type iterID = int;
1.145 +type calcID = int;
1.146 +
1.147 +(*FIXME.WN.9.03: ev. resdesign calcstate + pos for CalcIterator
1.148 +type state =
1.149 + (*pos' * set by the CalcIterator ---> for each user*)
1.150 + calcstate; (*to which ev.included 'preview' tac_s could be applied*)
1.151 +val e_state = (e_pos', e_calcstate):state;
1.152 +val states = ref ([]:(iterID * (calcID * state) list) list);
1.153 +*)
1.154 +
1.155 +val states =
1.156 + ref ([]:(calcID *
1.157 + (calcstate *
1.158 + (iterID * (*1 sets the 'active formula'*)
1.159 + pos' (*for iterator of a user *)
1.160 + ) list)) list);
1.161 +(*
1.162 +states:= [(3,(e_calcstate, [(1,e_pos'),
1.163 + (3,e_pos')])),
1.164 + (4,(e_calcstate, [(1,e_pos'),
1.165 + (2,e_pos')]))];
1.166 +*)
1.167 +
1.168 +(** create new instances of users and ptrees
1.169 + new keys are the lowest possible in the association list **)
1.170 +
1.171 +(* add users *)
1.172 +fun new_key u n = case assoc (u, n) of
1.173 + NONE => n
1.174 +| SOME _ => new_key u (n+1);
1.175 +(*///10.10
1.176 +fun get_calcID (u:(calcID * (calcstate * (iterID * pos') list)) list) =
1.177 + (new_key u 1):calcID;*)
1.178 +(*
1.179 +val new_iterID = get_calcID (!states);
1.180 +val it = 1 : int
1.181 +states:= (!states) @ [(new_iterID, [])];
1.182 +!states;
1.183 +val it = [(3,[(#,#),(#,#)]),(4,[(#,#),(#,#)]),(1,[])]
1.184 +*)
1.185 +
1.186 +(*///7.10.03/// add states to a users active states
1.187 +fun get_calcID (uI:iterID) (p:(iterID * (calcID * state) list) list) =
1.188 + case assoc (p, uI) of
1.189 + NONE => raise error ("get_calcID: no iterID " ^
1.190 + (string_of_int uI))
1.191 + | SOME ps => (new_key ps 1):calcID;
1.192 +> get_calcID 1 (!states);
1.193 +val it = 1 : calcID
1.194 +*)
1.195 +(* add users to a calcstate *)
1.196 +fun get_iterID (cI:calcID)
1.197 + (p:(calcID * (calcstate * (iterID * pos') list)) list) =
1.198 + case assoc (p, cI) of
1.199 + NONE => raise error ("get_iterID: no iterID " ^ (string_of_int cI))
1.200 + | SOME (_, us) => (new_key us 1):iterID;
1.201 +(* get_iterID 3 (!states);
1.202 +val it = 2 : iterID*)
1.203 +
1.204 +
1.205 +(** retrieve, update, delete a state by iterID, calcID **)
1.206 +
1.207 +(*//////7.10.
1.208 +fun get_cal (uI:iterID) (pI:calcID) (p:(iterID * (calcID * state) list) list) =
1.209 + (the (assoc2 (p,(uI, pI))))
1.210 + handle _ => raise error ("get_state " ^ (string_of_int uI) ^
1.211 + " " ^ (string_of_int pI) ^ " not existent");
1.212 +> get_cal 3 1 (!states);
1.213 +val it = (((EmptyPtree,(#,#)),[]),([],[])) : state
1.214 +*)
1.215 +
1.216 +(*///7.10.
1.217 +fun get_state (uI:iterID) (pI:calcID) = get_cal uI pI (!states);
1.218 +fun get_calc (uI:iterID) (pI:calcID) = (snd o (get_cal uI pI)) (!states);
1.219 +*)
1.220 +fun get_calc (cI:calcID) =
1.221 + case assoc (!states, cI) of
1.222 + NONE => raise error ("get_calc "^(string_of_int cI)^" not existent")
1.223 + | SOME (c, _) => c;
1.224 +fun get_pos (cI:calcID) (uI:iterID) =
1.225 + case assoc (!states, cI) of
1.226 + NONE => raise error ("get_pos: calc " ^ (string_of_int cI)
1.227 + ^ " not existent")
1.228 + | SOME (_, us) =>
1.229 + (case assoc (us, uI) of
1.230 + NONE => raise error ("get_pos: user " ^ (string_of_int uI)
1.231 + ^ " not existent")
1.232 + | SOME p => p);
1.233 +
1.234 +
1.235 +fun del_assoc ([],_) = []
1.236 + | del_assoc a =
1.237 + let fun del ([], key) ps = ps
1.238 + | del ((keyi, xi) :: pairs, key) ps =
1.239 + if key = keyi then ps @ pairs
1.240 + else del (pairs, key) (ps @ [(keyi, xi)])
1.241 + in del a [] end;
1.242 +(*
1.243 +> val ps = [(1,"1"),(2,"2"),(3,"3"),(4,"4")];
1.244 +> del_assoc (ps,3);
1.245 +val it = [(1,"1"),(2,"2"),(4,"4")] : (int * string) list
1.246 +*)
1.247 +
1.248 +(* delete doesn't report non existing elements *)
1.249 +(*/////7.10.
1.250 +fun del_assoc2 (uI:iterID) (pI:calcID) ps =
1.251 + let val new_ps = del_assoc (the (assoc (ps, uI)), pI)
1.252 + in overwrite (ps, (uI, new_ps)) end;*)
1.253 +(*
1.254 +> states:= del_assoc2 4 41 (!states);
1.255 +> !states;
1.256 +val it = [(3,[(#,#),(#,#),(#,#)]),(4,[(#,#)]),(1,[(#,#)])] : states
1.257 +
1.258 +> del_user 3;
1.259 +> !states;
1.260 +val it = [(4,[(#,#)]),(1,[(#,#)])] : states
1.261 +*)
1.262 +fun del_assoc2 (cI:calcID) (uI:iterID) ps =
1.263 + case assoc (ps, cI) of
1.264 + NONE => ps
1.265 + | SOME (cs, us) =>
1.266 + overwrite (ps, (cI, (cs, del_assoc (us, uI))));
1.267 +(*
1.268 +> del_assoc2 4 1 (!states);
1.269 +val it =
1.270 + [(3, (((EmptyPtree, ([], Und)), []), [(1, ([], Und)), (3, ([], Und))])),
1.271 + (4, (((EmptyPtree, ([], Und)), []), [(2, ([], Und))]))]*)
1.272 +
1.273 +(*///7.10.
1.274 +fun overwrite2 (ps, (((uI:iterID), (pI:calcID)), p)) =
1.275 + let val new_ps = overwrite (the (assoc (ps, uI)), (pI, p))
1.276 + in (overwrite (ps, (uI, new_ps)))
1.277 + handle _ => raise error ("overwrite2 " ^ (string_of_int uI) ^
1.278 + " " ^ (string_of_int pI) ^ " not existent")
1.279 + end;*)
1.280 +fun overwrite2 (ps, (((cI:calcID), (uI:iterID)), p)) =
1.281 + case assoc (ps, cI) of
1.282 + NONE =>
1.283 + raise error ("overwrite2: calc " ^ (string_of_int uI) ^" not existent")
1.284 + | SOME (cs, us) =>
1.285 + overwrite (ps, (cI ,(cs, overwrite (us, (uI, p)))));
1.286 +
1.287 +fun upd_calc (cI:calcID) cs =
1.288 + case assoc (!states, cI) of
1.289 + NONE => raise error ("upd_calc "^(string_of_int cI)^" not existent")
1.290 + | SOME (_, us) => states:= overwrite (!states, (cI, (cs, us)));
1.291 +(*WN051210 testing before initac: only 1 taci in calcstate so far:
1.292 +fun upd_calc (cI:calcID) (cs as (_, tacis):calcstate) =
1.293 + (if length tacis > 1
1.294 + then raise error ("upd_calc, |tacis|>1: "^tacis2str tacis)
1.295 + else ();
1.296 + case assoc (!states, cI) of
1.297 + NONE => raise error ("upd_calc "^(string_of_int cI)^" not existent")
1.298 + | SOME (_, us) => states:= overwrite (!states, (cI, (cs, us)))
1.299 + );*)
1.300 +
1.301 +
1.302 +(*///7.10.
1.303 +fun upd_tacis (uI:iterID) (pI:calcID) tacis =
1.304 + let val (p, (ptp,_)) = get_state uI pI
1.305 + in states:=
1.306 + overwrite2 ((!states), ((uI, pI), (p, (ptp, tacis)))) end;*)
1.307 +fun upd_tacis (cI:calcID) tacis =
1.308 + case assoc (!states, cI) of
1.309 + NONE =>
1.310 + raise error ("upd_tacis: calctree "^(string_of_int cI)^" not existent")
1.311 + | SOME ((ptp,_), us) =>
1.312 + states:= overwrite (!states, (cI, ((ptp, tacis), us)));
1.313 +(*///7.10.
1.314 +fun upd_ipos (uI:iterID) (pI:calcID) (ip:pos') =
1.315 + let val (_, calc) = get_state uI pI
1.316 + in states:= overwrite2 ((!states), ((uI, pI), (ip, calc))) end;*)
1.317 +fun upd_ipos (cI:calcID) (uI:iterID) (ip:pos') =
1.318 + case assoc (!states, cI) of
1.319 + NONE =>
1.320 + raise error ("upd_ipos: calctree "^(string_of_int cI)^" not existent")
1.321 + | SOME (cs, us) =>
1.322 + states:= overwrite2 (!states, ((cI, uI), ip));
1.323 +
1.324 +
1.325 +(** add and delete calcs **)
1.326 +
1.327 +(*///7.10
1.328 +fun add_pID (uI:iterID) (s:state) (p:(iterID * (calcID * state) list) list) =
1.329 + let val new_ID = get_calcID uI p;
1.330 + val new_states = (the (assoc (p, uI))) @ [(new_ID, s)];
1.331 + in (new_ID, (overwrite (p, (uI, new_states)))) end;*)
1.332 +(*
1.333 +> val (new_calcID, new_states) = add_pID 1 (!states);
1.334 +> states:= new_states;
1.335 +> !states;
1.336 +val it = [(3,[(#,#),(#,#)]),(4,[(#,#),(#,#)]),(1,[(#,#)])] : states
1.337 +> val (new_calcID, new_states) = add_pID 3 (!states);
1.338 +> states:= new_states;
1.339 +> !states;
1.340 +val it = [(3,[(#,#),(#,#),(#,#)]),(4,[(#,#),(#,#)]),(1,[(#,#)])] : states
1.341 +> assoc2 (!states, (3, 1));
1.342 +val it = SOME EmptyPtree : ptree option
1.343 +> assoc2 (!states, (3, 2));
1.344 +val it = NONE : ptree option
1.345 +*)
1.346 +(*///7.10
1.347 +fun add_calc (uI:iterID) (s:state) =
1.348 + let val (new_calcID, new_calcs) = add_pID uI s (!states)
1.349 + in states:= new_calcs;
1.350 + new_calcID end; *)
1.351 +fun add_user (cI:calcID) =
1.352 + case assoc (!states, cI) of
1.353 + NONE =>
1.354 + raise error ("add_user: calctree "^(string_of_int cI)^" not existent")
1.355 + | SOME (cs, us) =>
1.356 + let val new_uI = new_key us 1
1.357 + in states:= overwrite2 (!states, ((cI, new_uI), e_pos'));
1.358 + new_uI:iterID end;
1.359 +
1.360 +(*///10.10.
1.361 +fun del_calc (uI:iterID) (pI:calcID) =
1.362 + (states:= del_assoc2 uI pI (!states); pI);*)
1.363 +fun del_user (cI:calcID) (uI:iterID) =
1.364 + (states:= del_assoc2 cI uI (!states); uI);
1.365 +
1.366 +
1.367 +(** add and delete calculations **)
1.368 +(**///7.10 add and delete users **)
1.369 +(*///7.10
1.370 +fun add_user () =
1.371 + let val new_uI = get_calcID (!states)
1.372 + in states:= (!states) @ [(new_uI, [])];
1.373 + new_uI end;*)
1.374 +fun add_calc (cs:calcstate) =
1.375 + let val new_cI = new_key (!states) 1
1.376 + in states:= (!states) @ [(new_cI, (cs, []))];
1.377 + new_cI:calcID end;
1.378 +
1.379 +(* delete doesn't report non existing elements *)
1.380 +(*///7.10
1.381 +fun del_user (uI:userID) =
1.382 + (states:= del_assoc (!states, uI); uI);*)
1.383 +fun del_calc (cI:calcID) =
1.384 + (states:= del_assoc (!states, cI); cI:calcID);
1.385 +
1.386 +(* -------------- test all exported funs --------------
1.387 +///7.10
1.388 +Compiler.Control.Print.printDepth:=8;
1.389 +states:=[];
1.390 +add_user (); add_user (); !states;
1.391 +ML> val it = 1 : userID
1.392 +ML> val it = 2 : userID
1.393 +ML> val it = [(1,[]),(2,[])]
1.394 +
1.395 +val (hide,detail) = ([(["pI"],["tac"],true)]:hide,
1.396 + [(["pI"],["tac"],true)]:detail);
1.397 +add_calc 1 e_state;
1.398 +add_calc 1 (e_calcstate,(hide,detail)); !states;
1.399 +ML> val it = 1 : calcID
1.400 +ML> val it = 2 : calcID
1.401 +ML> val it =
1.402 + [(1,
1.403 + [(1,(((EmptyPtree,(#,#)),[]),([],[]))),
1.404 + (2,(((EmptyPtree,(#,#)),[]),([(#,#,#)],[(#,#,#)])))]),(2,[])]
1.405 +
1.406 +val (pt,(p,p_)) = (EmptyPtree,e_pos');
1.407 +val (pt,_) = cappend_problem pt p Uistate ([],e_spec);
1.408 +upd_calc 1 2 ((pt,(p,p_)),[]); !states;
1.409 +ML> val it =
1.410 + [(1,
1.411 + [(1,(((EmptyPtree,(#,#)),[]),([],[]))),
1.412 + (2,(((Nd #,(#,#)),[]),([(#,#,#)],[(#,#,#)])))]),(2,[])]
1.413 +(* ~~~~~~~~~~~~~~~~~~~~ unchanged !!!*)
1.414 +
1.415 +get_state 1 1; get_state 1 2;
1.416 +ML> val it = (((EmptyPtree,([],Und)),[]),([],[])) : state
1.417 +ML> val it =
1.418 + (((Nd
1.419 + (PblObj
1.420 + {branch=NoBranch,cell=[],env=(#,#,#,#),loc=(#,#),meth=[],
1.421 + model={Find=#,Given=#,Relate=#,Where=#,With=#},origin=(#,#),
1.422 + ostate=Incomplete,probl=[],result=(#,#),spec=(#,#,#)},[]),([],Und)),
1.423 + []),([(["pI"],["tac"],true)],[(["pI"],["tac"],true)])) : state
1.424 +
1.425 +del_calc 2 1 (*non existent - NO msg!*); del_calc 1 2; !states;
1.426 +ML> val it = [(1,[(1,(((EmptyPtree,(#,#)),[]),([],[])))]),(2,[])]
1.427 +
1.428 +del_user 1; !states;
1.429 +ML> val it = [(2,[])]
1.430 +
1.431 +add_user (); add_user (); !states;
1.432 +ML> val it = 1 : userID
1.433 +ML> val it = 3 : userID
1.434 +ML> val it = [(2,[]),(1,[]),(3,[])]
1.435 +*)
1.436 +
1.437 +
1.438 +(* -------------- test all exported funs --------------
1.439 +print_depth 9;
1.440 +states:=[];
1.441 +add_calc e_calcstate; add_calc e_calcstate; !states;
1.442 +|val it = 1 : calcID
1.443 +|val it = 2 : calcID
1.444 +|val it =
1.445 +| [(1, (((EmptyPtree, ([], Und)), []), [])),
1.446 +| (2, (((EmptyPtree, ([], Und)), []), []))]
1.447 +
1.448 +add_user 2; add_user 2; !states;
1.449 +|val it = 1 : userID
1.450 +|val it = 2 : userID
1.451 +|val it =
1.452 +| [(1, (((EmptyPtree, ([], Und)), []), [])),
1.453 +| (2, (((EmptyPtree, ([], Und)), []), [(1, ([], Und)), (2, ([], Und))]))]
1.454 +
1.455 +
1.456 +val cs = ((EmptyPtree, ([111], Und)), []) : calcstate;
1.457 +upd_calc 1 cs; !states;
1.458 +|val it =
1.459 +| [(1, (((EmptyPtree, ([111], Und)), []), [])),
1.460 +| (2, (((EmptyPtree, ([], Und)), []), [(1, ([], Und)), (2, ([], Und))]))]
1.461 +
1.462 +get_calc 1; get_calc 2;
1.463 +|val it = ((EmptyPtree, ([111], Und)), []) : calcstate
1.464 +|val it = ((EmptyPtree, ([], Und)), []) : calcstate
1.465 +
1.466 +del_user 2 3 (*non existent - NO msg!*); del_user 2 1; !states;
1.467 +|val it = 3 : userID
1.468 +|val it = 1 : userID
1.469 +|val it =
1.470 +| [(1, (((EmptyPtree, ([111], Und)), []), [])),
1.471 +| (2, (((EmptyPtree, ([], Und)), []), [(2, ([], Und))]))]
1.472 +
1.473 +del_calc 1; !states;
1.474 +|val it = 1 : calcID
1.475 +|val it = [(2, (((EmptyPtree, ([], Und)), []), [(2, ([], Und))]))]
1.476 +
1.477 +add_calc e_calcstate; add_calc e_calcstate; !states;
1.478 +|val it = 1 : calcID
1.479 +|val it = 3 : calcID
1.480 +|val it =
1.481 +| [(2, (((EmptyPtree, ([], Und)), []), [(2, ([], Und))])),
1.482 +| (1, (((EmptyPtree, ([], Und)), []), [])),
1.483 +| (3, (((EmptyPtree, ([], Und)), []), []))]
1.484 +
1.485 +add_user 2; !states;
1.486 +|val it =
1.487 +| [(2, (((EmptyPtree, ([], Und)), []), [(2, ([], Und)), (1, ([], Und))])),
1.488 +| (1, (((EmptyPtree, ([], Und)), []), [])),
1.489 +| (3, (((EmptyPtree, ([], Und)), []), []))]
1.490 +*)
1.491 \ No newline at end of file