/[svn]/types/types.ml
ViewVC logotype

Diff of /types/types.ml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 109 by abate, Tue Jul 10 17:05:54 2007 UTC revision 110 by abate, Tue Jul 10 17:07:14 2007 UTC
# Line 20  Line 20 
20    
21  type const = Integer of Big_int.big_int | Atom of atom | Char of Chars.Unichar.t  type const = Integer of Big_int.big_int | Atom of atom | Char of Chars.Unichar.t
22    
23    type pair_kind = [ `Normal | `XML ]
24    
25  module I = struct  module I = struct
26    type 'a t = {    type 'a t = {
27      ints  : Intervals.t;      ints  : Intervals.t;
28      atoms : atom Atoms.t;      atoms : atom Atoms.t;
29      times : ('a * 'a) Boolean.t;      times : ('a * 'a) Boolean.t;
30        xml   : ('a * 'a) Boolean.t;
31      arrow : ('a * 'a) Boolean.t;      arrow : ('a * 'a) Boolean.t;
32      record: (label * bool * 'a) Boolean.t;      record: (label * bool * 'a) Boolean.t;
33      chars : Chars.t;      chars : Chars.t;
# Line 32  Line 35 
35    
36    let empty = {    let empty = {
37      times = Boolean.empty;      times = Boolean.empty;
38        xml   = Boolean.empty;
39      arrow = Boolean.empty;      arrow = Boolean.empty;
40      record= Boolean.empty;      record= Boolean.empty;
41      ints  = Intervals.empty;      ints  = Intervals.empty;
42      atoms = Atoms.empty;      atoms = Atoms.empty;
43      chars = Chars.empty;      chars = Chars.empty;
44    }    }
45    (*
46    let any =  {    let any =  {
47      times = Boolean.full;      times = Boolean.full;
48        xml   = Boolean.full;
49      arrow = Boolean.full;      arrow = Boolean.full;
50      record= Boolean.full;      record= Boolean.full;
51      ints  = Intervals.any;      ints  = Intervals.any;
52      atoms = Atoms.any;      atoms = Atoms.any;
53      chars = Chars.any;      chars = Chars.any;
54    }    }
55    *)
56    
57    let interval i = { empty with ints = i }    let interval i = { empty with ints = i }
58    let times x y = { empty with times = Boolean.atom (x,y) }    let times x y = { empty with times = Boolean.atom (x,y) }
59      let xml x y = { empty with xml = Boolean.atom (x,y) }
60    let arrow x y = { empty with arrow = Boolean.atom (x,y) }    let arrow x y = { empty with arrow = Boolean.atom (x,y) }
61    let record label opt t = { empty with record = Boolean.atom (label,opt,t) }    let record label opt t = { empty with record = Boolean.atom (label,opt,t) }
62    let atom a = { empty with atoms = a }    let atom a = { empty with atoms = a }
# Line 60  Line 67 
67      | Char c -> char (Chars.atom c)      | Char c -> char (Chars.atom c)
68    
69    
   let any_record = { empty with record = any.record }  
   
70    let cup x y =    let cup x y =
71      if x = y then x else {      if x = y then x else {
72        times = Boolean.cup x.times y.times;        times = Boolean.cup x.times y.times;
73          xml   = Boolean.cup x.xml y.xml;
74        arrow = Boolean.cup x.arrow y.arrow;        arrow = Boolean.cup x.arrow y.arrow;
75        record= Boolean.cup x.record y.record;        record= Boolean.cup x.record y.record;
76        ints  = Intervals.cup x.ints  y.ints;        ints  = Intervals.cup x.ints  y.ints;
# Line 75  Line 81 
81    let cap x y =    let cap x y =
82      if x = y then x else {      if x = y then x else {
83        times = Boolean.cap x.times y.times;        times = Boolean.cap x.times y.times;
84          xml   = Boolean.cap x.xml y.xml;
85        record= Boolean.cap x.record y.record;        record= Boolean.cap x.record y.record;
86        arrow = Boolean.cap x.arrow y.arrow;        arrow = Boolean.cap x.arrow y.arrow;
87        ints  = Intervals.cap x.ints  y.ints;        ints  = Intervals.cap x.ints  y.ints;
# Line 85  Line 92 
92    let diff x y =    let diff x y =
93      if x = y then empty else {      if x = y then empty else {
94        times = Boolean.diff x.times y.times;        times = Boolean.diff x.times y.times;
95          xml   = Boolean.diff x.xml y.xml;
96        arrow = Boolean.diff x.arrow y.arrow;        arrow = Boolean.diff x.arrow y.arrow;
97        record= Boolean.diff x.record y.record;        record= Boolean.diff x.record y.record;
98        ints  = Intervals.diff x.ints  y.ints;        ints  = Intervals.diff x.ints  y.ints;
# Line 92  Line 100 
100        chars = Chars.diff x.chars y.chars;        chars = Chars.diff x.chars y.chars;
101      }      }
102    
   let neg x = diff any x  
103    
104    let equal e a b =    let equal e a b =
105      if a.atoms <> b.atoms then raise NotEqual;      if a.atoms <> b.atoms then raise NotEqual;
106      if a.chars <> b.chars then raise NotEqual;      if a.chars <> b.chars then raise NotEqual;
107      if a.ints <> b.ints then raise NotEqual;      if a.ints <> b.ints then raise NotEqual;
108      Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.times b.times;      Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.times b.times;
109        Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.xml b.xml;
110      Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.arrow b.arrow;      Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.arrow b.arrow;
111      Boolean.equal (fun (l1,o1,x1) (l2,o2,x2) ->      Boolean.equal (fun (l1,o1,x1) (l2,o2,x2) ->
112                       if (l1 <> l2) || (o1 <> o2) then raise NotEqual;                       if (l1 <> l2) || (o1 <> o2) then raise NotEqual;
# Line 106  Line 114 
114    
115    let map f a =    let map f a =
116      { times = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.times;      { times = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.times;
117          xml   = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.xml;
118        arrow = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.arrow;        arrow = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.arrow;
119        record= Boolean.map (fun (l,o,x) -> (l,o, f x)) a.record;        record= Boolean.map (fun (l,o,x) -> (l,o, f x)) a.record;
120        ints  = a.ints;        ints  = a.ints;
# Line 139  Line 148 
148      end      end
149    )    )
150    
151    (*
152    let define n d = check d; define n d
153    *)
154    
155    let cons d =
156      let n = make () in
157      define n d;
158      internalize n
159    
160    let any_rec = cons { empty with record = Boolean.full }
161    let any_node = make ();;
162    define any_node   {
163      times = Boolean.full;
164      xml   = Boolean.atom
165                (cons { empty with atoms = Atoms.any },
166                 cons (times any_rec any_node));
167      arrow = Boolean.full;
168      record= Boolean.full;
169      ints  = Intervals.any;
170      atoms = Atoms.any;
171      chars = Chars.any;
172    };;
173    internalize any_node;;
174    let any = descr any_node
175    
176    let neg x = diff any x
177    
178    let get_record r =
179      let add = SortedMap.add (fun (o1,t1) (o2,t2) -> (o1&&o2, cap t1 t2)) in
180      let line (p,n) =
181        let accu = List.fold_left
182                     (fun accu (l,o,t) -> add l (o,descr t) accu) [] p in
183        List.fold_left
184          (fun accu (l,o,t) -> add l (not o,neg (descr t)) accu) accu n in
185      List.map line r
186    
187    
188  module DescrMap = Map.Make(struct type t = descr let compare = compare end)  module DescrMap = Map.Make(struct type t = descr let compare = compare end)
189    
190  let check d =  let check d =
191    Boolean.check d.times;    Boolean.check d.times;
192      Boolean.check d.xml;
193    Boolean.check d.arrow;    Boolean.check d.arrow;
194    Boolean.check d.record;    Boolean.check d.record;
195    ()    ()
196    
197    
198    
199    (* Subtyping algorithm *)
200    
201    let diff_t d t = diff d (descr t)
202    let cap_t d t = cap d (descr t)
203    let cup_t d t = cup d (descr t)
204    let cap_product l =
205      List.fold_left
206        (fun (d1,d2) (t1,t2) -> (cap_t d1 t1, cap_t d2 t2))
207        (any,any)
208        l
209    
210    
211    let cup_product l =
212      List.fold_left
213        (fun (d1,d2) (t1,t2) -> (cup_t d1 t1, cup_t d2 t2))
214        (empty,empty)
215        l
216    
217    
218    module Assumptions = Set.Make(struct type t = descr let compare = compare end)
219    
220    let memo = ref Assumptions.empty
221    let cache_false = ref Assumptions.empty
222    
223    exception NotEmpty
224    
225    let rec empty_rec d =
226      if Assumptions.mem d !cache_false then false
227      else if Assumptions.mem d !memo then true
228      else if not (Intervals.is_empty d.ints) then false
229      else if not (Atoms.is_empty d.atoms) then false
230      else if not (Chars.is_empty d.chars) then false
231      else (
232        let backup = !memo in
233        memo := Assumptions.add d backup;
234        if
235          (empty_rec_times d.times) &&
236          (empty_rec_times d.xml) &&
237          (empty_rec_arrow d.arrow) &&
238          (empty_rec_record d.record)
239        then true
240        else (
241          memo := backup;
242          cache_false := Assumptions.add d !cache_false;
243          false
244        )
245      )
246    
247    and empty_rec_times c =
248      List.for_all empty_rec_times_aux c
249    
250    and empty_rec_times_aux (left,right) =
251      let rec aux accu1 accu2 = function
252        | (t1,t2)::right ->
253            let accu1' = diff_t accu1 t1 in
254            if not (empty_rec accu1') then aux accu1' accu2 right;
255            let accu2' = diff_t accu2 t2 in
256            if not (empty_rec accu2') then aux accu1 accu2' right
257        | [] -> raise NotEmpty
258      in
259      let (accu1,accu2) = cap_product left in
260      (empty_rec accu1) || (empty_rec accu2) ||
261    (* OPT? It does'nt seem so ...  The hope was to return false quickly
262       for large right hand-side *)
263      (
264        ((*if (List length right > 2) then
265           let (cup1,cup2) = cup_product right in
266           (empty_rec (diff accu1 cup1)) && (empty_rec (diff accu2 cup2))
267         else*) true)
268        &&
269        (try aux accu1 accu2 right; true with NotEmpty -> false)
270      )
271    
272    and empty_rec_arrow c =
273      List.for_all empty_rec_arrow_aux c
274    
275    and empty_rec_arrow_aux (left,right) =
276      let single_right (s1,s2) =
277        let rec aux accu1 accu2 = function
278          | (t1,t2)::left ->
279              let accu1' = diff_t accu1 t1 in
280              if not (empty_rec accu1') then aux accu1 accu2 left;
281              let accu2' = cap_t accu2 t2 in
282              if not (empty_rec accu2') then aux accu1 accu2 left
283          | [] -> raise NotEmpty
284        in
285        let accu1 = descr s1 in
286        (empty_rec accu1) ||
287        (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)
288      in
289      List.exists single_right right
290    
291    and empty_rec_record c =
292      let aux = List.exists (fun (_,(opt,t)) -> (not opt) && (empty_rec t)) in
293      List.for_all aux (get_record c)
294    
295    let is_empty d =
296      let old = !memo in
297      let r = empty_rec d in
298      if not r then memo := old;
299    (*  cache_false := Assumptions.empty;  *)
300      r
301    
302    let non_empty d =
303      not (is_empty d)
304    
305    let subtype d1 d2 =
306      is_empty (diff d1 d2)
307    
308    module Product =
309    struct
310      type t = (descr * descr) list
311    
312      let other ?(kind=`Normal) d =
313        match kind with
314          | `Normal -> { d with times = empty.times }
315          | `XML -> { d with xml = empty.xml }
316    
317      let is_product ?kind d = is_empty (other ?kind d)
318    
319      let need_second = function _::_::_ -> true | _ -> false
320    
321      let normal_aux d =
322        let res = ref [] in
323    
324        let add (t1,t2) =
325          let rec loop t1 t2 = function
326            | [] -> res := (ref (t1,t2)) :: !res
327            | ({contents = (d1,d2)} as r)::l ->
328                (*OPT*)
329                if d1 = t1 then r := (d1,cup d2 t2) else
330    
331                  let i = cap t1 d1 in
332                  if is_empty i then loop t1 t2 l
333                  else (
334                    r := (i, cup t2 d2);
335                    let k = diff d1 t1 in
336                    if non_empty k then res := (ref (k,d2)) :: !res;
337    
338                    let j = diff t1 d1 in
339                    if non_empty j then loop j t2 l
340                  )
341          in
342          loop t1 t2 !res
343        in
344        List.iter add d;
345        List.map (!) !res
346    
347  (*  (*
348  let define n d = check d; define n d  This version explodes when dealing with
349       Any - [ t1? t2? t3? ... tn? ]
350    ==> need partitioning
351  *)  *)
352      let get_aux d =
353        let line accu (left,right) =
354          let rec aux accu d1 d2 = function
355            | (t1,t2)::right ->
356                let accu =
357                  let d1 = diff_t d1 t1 in
358                  if is_empty d1 then accu else aux accu d1 d2 right in
359                let accu =
360                  let d2 = diff_t d2 t2 in
361                  if is_empty d2 then accu else aux accu d1 d2 right in
362                accu
363            | [] -> (d1,d2) :: accu
364          in
365          let (d1,d2) = cap_product left in
366          if (is_empty d1) || (is_empty d2) then accu else aux accu d1 d2 right
367        in
368        List.fold_left line [] d
369    
370  let cons d =  (* Partitioning:
371    let n = make () in  
372    define n d;  (t,s) - ((t1,s1) | (t2,s2) | ... | (tn,sn))
373    internalize n  =
374    (t & t1, s - s1) | ... | (t & tn, s - sn) | (t - (t1|...|tn), s)
375    
376    *)
377    
378      let get_aux d =
379        let accu = ref [] in
380        let line (left,right) =
381          let (d1,d2) = cap_product left in
382          if (non_empty d1) && (non_empty d2) then
383            let right = List.map (fun (t1,t2) -> descr t1, descr t2) right in
384            let right = normal_aux right in
385            let resid1 = ref d1 in
386            let () =
387              List.iter
388                (fun (t1,t2) ->
389                   let t1 = cap d1 t1 in
390                   if (non_empty t1) then
391                     let () = resid1 := diff !resid1 t1 in
392                     let t2 = diff d2 t2 in
393                     if (non_empty t2) then accu := (t1,t2) :: !accu
394                ) right in
395            if non_empty !resid1 then accu := (!resid1, d2) :: !accu
396        in
397        List.iter line d;
398        !accu
399    
400      let get ?(kind=`Normal) d =
401        match kind with
402          | `Normal -> get_aux d.times
403          | `XML -> get_aux d.xml
404    
405      let pi1 = List.fold_left (fun acc (t1,_) -> cup acc t1) empty
406      let pi2 = List.fold_left (fun acc (_,t2) -> cup acc t2) empty
407    
408      let restrict_1 rects pi1 =
409        let aux accu (t1,t2) =
410          let t1 = cap t1 pi1 in if is_empty t1 then accu else (t1,t2)::accu in
411        List.fold_left aux [] rects
412    
413      type normal = t
414    
415      module Memo = Map.Make(struct
416                               type t = (node * node) Boolean.t
417                               let compare = compare end)
418    
419    
420    
421      let memo = ref Memo.empty
422      let normal ?(kind=`Normal) d =
423        let d = match kind with `Normal -> d.times | `XML -> d.xml in
424        try Memo.find d !memo
425        with
426            Not_found ->
427              let gd = get_aux d in
428              let n = normal_aux gd in
429              memo := Memo.add d n !memo;
430              n
431    
432      let any = { empty with times = any.times }
433      and any_xml = { empty with xml = any.xml }
434      let is_empty d = d = []
435    end
436    
437  module Print =  module Print =
438  struct  struct
439      let rec print_union ppf = function
440        | [] -> Format.fprintf ppf "Empty"
441        | [h] -> h ppf
442        | h::t -> Format.fprintf ppf "@[%t |@ %a@]" h print_union t
443    
444    let print_atom ppf a =    let print_atom ppf a =
445      Format.fprintf ppf "`%s" (AtomPool.value a)      Format.fprintf ppf "`%s" (AtomPool.value a)
446    
447      let print_tag ppf a =
448        match Atoms.is_atom a with
449          | Some a -> Format.fprintf ppf "%s" (AtomPool.value a)
450          | None ->
451              Format.fprintf ppf "(%a)"
452                print_union
453                   (Atoms.print "Atom" print_atom a)
454    
455    let print_const ppf = function    let print_const ppf = function
456      | Integer i -> Format.fprintf ppf "%s" (Big_int.string_of_big_int i)      | Integer i -> Format.fprintf ppf "%s" (Big_int.string_of_big_int i)
457      | Atom a -> print_atom ppf a      | Atom a -> print_atom ppf a
# Line 200  Line 490 
490        with Not_found ->        with Not_found ->
491          DescrHash.add marks d (ref None);          DescrHash.add marks d (ref None);
492          bool_iter (fun (n1,n2) -> mark n1; mark n2) d.times;          bool_iter (fun (n1,n2) -> mark n1; mark n2) d.times;
493            bool_iter (fun (n1,n2) -> mark n1; mark n2) d.xml;
494          bool_iter (fun (n1,n2) -> mark n1; mark n2) d.arrow;          bool_iter (fun (n1,n2) -> mark n1; mark n2) d.arrow;
495          bool_iter (fun (l,o,n) -> mark n) d.record          bool_iter (fun (l,o,n) -> mark n) d.record
496    
497    
   let rec print_union ppf = function  
     | [] -> Format.fprintf ppf "Empty"  
     | [h] -> h ppf  
     | h::t -> Format.fprintf ppf "@[%t |@ %a@]" h print_union t  
   
   
498    let rec print ppf n = print_descr ppf (descr n)    let rec print ppf n = print_descr ppf (descr n)
499    and print_descr ppf d =    and print_descr ppf d =
500      try      try
# Line 221  Line 506 
506            | Some n -> Format.fprintf ppf "%s" n            | Some n -> Format.fprintf ppf "%s" n
507            | None -> real_print_descr ppf d            | None -> real_print_descr ppf d
508        with        with
509            Not_found -> Format.fprintf ppf "XXX"            Not_found -> assert false
510    and real_print_descr ppf d =    and real_print_descr ppf d =
511      if d = any then Format.fprintf ppf "Any" else      if d = any then Format.fprintf ppf "Any" else
512        print_union ppf        print_union ppf
# Line 229  Line 514 
514           Chars.print d.chars @           Chars.print d.chars @
515           Atoms.print "Atom" print_atom d.atoms @           Atoms.print "Atom" print_atom d.atoms @
516           Boolean.print "Pair" print_times d.times @           Boolean.print "Pair" print_times d.times @
517             Boolean.print "XML" print_xml d.xml @
518           Boolean.print "Arrow" print_arrow d.arrow @           Boolean.print "Arrow" print_arrow d.arrow @
519           Boolean.print "Record" print_record d.record           Boolean.print "Record" print_record d.record
520          )          )
521    and print_times ppf (t1,t2) =    and print_times ppf (t1,t2) =
522      Format.fprintf ppf "@[(%a,%a)@]" print t1 print t2      Format.fprintf ppf "@[(%a,%a)@]" print t1 print t2
523      and print_xml ppf (t1,t2) =
524        let l = Product.normal (descr t2) in
525        let l = List.map
526                  (fun (d1,d2) ppf ->
527                     Format.fprintf ppf "@[<><%a%a>%a@]"
528                       print_tag (descr t1).atoms
529                       print_attribs d1.record
530                       print_descr d2) l
531        in
532        print_union ppf l
533    and print_arrow ppf (t1,t2) =    and print_arrow ppf (t1,t2) =
534      Format.fprintf ppf "@[(%a -> %a)@]" print t1 print t2      Format.fprintf ppf "@[(%a -> %a)@]" print t1 print t2
535    and print_record ppf (l,o,t) =    and print_record ppf (l,o,t) =
536      Format.fprintf ppf "@[{ %s =%s %a }@]"      Format.fprintf ppf "@[{ %s =%s %a }@]"
537        (LabelPool.value l) (if o then "?" else "") print t        (LabelPool.value l) (if o then "?" else "") print t
538      and print_attribs ppf r =
539        let l = get_record r in
540        if l <> [ [] ] then
541        let l = List.map
542          (fun att ppf ->
543             let first = ref true in
544             Format.fprintf ppf "{" ;
545             List.iter (fun (l,(o,d)) ->
546                          Format.fprintf ppf "%s%s=%s%a"
547                            (if !first then "" else " ")
548                            (LabelPool.value l) (if o then "?" else "")
549                            print_descr d;
550                          first := false
551                       ) att;
552               Format.fprintf ppf "}"
553          ) l in
554        print_union ppf l
555    
556    
557    let end_print ppf =    let end_print ppf =
# Line 306  Line 619 
619  end  end
620    
621    
 let get_record r =  
   let add = SortedMap.add (fun (o1,t1) (o2,t2) -> (o1&&o2, cap t1 t2)) in  
   let line (p,n) =  
     let accu = List.fold_left  
                  (fun accu (l,o,t) -> add l (o,descr t) accu) [] p in  
     List.fold_left  
       (fun accu (l,o,t) -> add l (not o,neg (descr t)) accu) accu n in  
   List.map line r  
   
   
   
 (* Subtyping algorithm *)  
   
 let diff_t d t = diff d (descr t)  
 let cap_t d t = cap d (descr t)  
 let cup_t d t = cup d (descr t)  
 let cap_product l =  
   List.fold_left  
     (fun (d1,d2) (t1,t2) -> (cap_t d1 t1, cap_t d2 t2))  
     (any,any)  
     l  
 let cup_product l =  
   List.fold_left  
     (fun (d1,d2) (t1,t2) -> (cup_t d1 t1, cup_t d2 t2))  
     (empty,empty)  
     l  
   
   
 module Assumptions = Set.Make(struct type t = descr let compare = compare end)  
   
 let memo = ref Assumptions.empty  
 let cache_false = ref Assumptions.empty  
   
 exception NotEmpty  
   
 let rec empty_rec d =  
   if Assumptions.mem d !cache_false then false  
   else if Assumptions.mem d !memo then true  
   else if not (Intervals.is_empty d.ints) then false  
   else if not (Atoms.is_empty d.atoms) then false  
   else if not (Chars.is_empty d.chars) then false  
   else (  
     let backup = !memo in  
     memo := Assumptions.add d backup;  
     if  
       (empty_rec_times d.times) &&  
       (empty_rec_arrow d.arrow) &&  
       (empty_rec_record d.record)  
     then true  
     else (  
       memo := backup;  
       cache_false := Assumptions.add d !cache_false;  
       false  
     )  
   )  
   
 and empty_rec_times c =  
   List.for_all empty_rec_times_aux c  
   
 and empty_rec_times_aux (left,right) =  
   let rec aux accu1 accu2 = function  
     | (t1,t2)::right ->  
         let accu1' = diff_t accu1 t1 in  
         if not (empty_rec accu1') then aux accu1' accu2 right;  
         let accu2' = diff_t accu2 t2 in  
         if not (empty_rec accu2') then aux accu1 accu2' right  
     | [] -> raise NotEmpty  
   in  
   let (accu1,accu2) = cap_product left in  
   (empty_rec accu1) || (empty_rec accu2) ||  
 (* OPT? It does'nt seem so ...  The hope was to return false quickly  
    for large right hand-side *)  
   (  
     ((*if (List length right > 2) then  
        let (cup1,cup2) = cup_product right in  
        (empty_rec (diff accu1 cup1)) && (empty_rec (diff accu2 cup2))  
      else*) true)  
     &&  
     (try aux accu1 accu2 right; true with NotEmpty -> false)  
   )  
   
 and empty_rec_arrow c =  
   List.for_all empty_rec_arrow_aux c  
   
 and empty_rec_arrow_aux (left,right) =  
   let single_right (s1,s2) =  
     let rec aux accu1 accu2 = function  
       | (t1,t2)::left ->  
           let accu1' = diff_t accu1 t1 in  
           if not (empty_rec accu1') then aux accu1 accu2 left;  
           let accu2' = cap_t accu2 t2 in  
           if not (empty_rec accu2') then aux accu1 accu2 left  
       | [] -> raise NotEmpty  
     in  
     let accu1 = descr s1 in  
     (empty_rec accu1) ||  
     (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)  
   in  
   List.exists single_right right  
622    
 and empty_rec_record c =  
   let aux = List.exists (fun (_,(opt,t)) -> (not opt) && (empty_rec t)) in  
   List.for_all aux (get_record c)  
   
 let is_empty d =  
   let old = !memo in  
   let r = empty_rec d in  
   if not r then memo := old;  
 (*  cache_false := Assumptions.empty;  *)  
   r  
   
 let non_empty d =  
   not (is_empty d)  
   
 let subtype d1 d2 =  
   is_empty (diff d1 d2)  
623    
624  (* Sample value *)  (* Sample value *)
625  module Sample =  module Sample =
# Line 435  Line 633 
633    | Int of Big_int.big_int    | Int of Big_int.big_int
634    | Atom of atom    | Atom of atom
635    | Char of Chars.Unichar.t    | Char of Chars.Unichar.t
636    | Pair of t * t    | Pair of (t * t)
637      | Xml of (t * t)
638    | Record of (label * t) list    | Record of (label * t) list
639    | Fun of (node * node) list    | Fun of (node * node) list
640    
# Line 450  Line 649 
649      try sample_rec_arrow d.arrow with Not_found ->      try sample_rec_arrow d.arrow with Not_found ->
650    
651      let memo = Assumptions.add d memo in      let memo = Assumptions.add d memo in
652      try sample_rec_times memo d.times with Not_found ->      try Pair (sample_rec_times memo d.times) with Not_found ->
653        try Xml (sample_rec_times memo d.xml) with Not_found ->
654      try sample_rec_record memo d.record with Not_found ->      try sample_rec_record memo d.record with Not_found ->
655      raise Not_found      raise Not_found
656    
# Line 466  Line 666 
666            let accu2' = diff_t accu2 t2 in            let accu2' = diff_t accu2 t2 in
667            if non_empty accu2' then aux accu1 accu2' right else            if non_empty accu2' then aux accu1 accu2' right else
668              raise Not_found              raise Not_found
669      | [] -> Pair (sample_rec memo accu1, sample_rec memo accu2)      | [] -> (sample_rec memo accu1, sample_rec memo accu2)
670    in    in
671    let (accu1,accu2) = cap_product left in    let (accu1,accu2) = cap_product left in
672    if (is_empty accu1) || (is_empty accu2) then raise Not_found;    if (is_empty accu1) || (is_empty accu2) then raise Not_found;
# Line 520  Line 720 
720            Format.fprintf ppf "`%s" (AtomPool.value a)            Format.fprintf ppf "`%s" (AtomPool.value a)
721      | Char c -> Chars.Unichar.print ppf c      | Char c -> Chars.Unichar.print ppf c
722      | Pair (x1,x2) -> Format.fprintf ppf "(%a,%a)" print x1 print x2      | Pair (x1,x2) -> Format.fprintf ppf "(%a,%a)" print x1 print x2
723        | Xml (x1,x2) -> Format.fprintf ppf "XML(%a,%a)" print x1 print x2
724      | Record r ->      | Record r ->
725          Format.fprintf ppf "{ %a }"          Format.fprintf ppf "{ %a }"
726            (print_sep            (print_sep
# Line 542  Line 743 
743  end  end
744    
745    
 module Product =  
 struct  
   type t = (descr * descr) list  
   
   let other d = { d with times = empty.times }  
   let is_product d = is_empty (other d)  
   
   let need_second = function _::_::_ -> true | _ -> false  
   
   let normal_aux d =  
     let res = ref [] in  
   
     let add (t1,t2) =  
       let rec loop t1 t2 = function  
         | [] -> res := (ref (t1,t2)) :: !res  
         | ({contents = (d1,d2)} as r)::l ->  
             (*OPT*)  
             if d1 = t1 then r := (d1,cup d2 t2) else  
   
               let i = cap t1 d1 in  
               if is_empty i then loop t1 t2 l  
               else (  
                 r := (i, cup t2 d2);  
                 let k = diff d1 t1 in  
                 if non_empty k then res := (ref (k,d2)) :: !res;  
   
                 let j = diff t1 d1 in  
                 if non_empty j then loop j t2 l  
               )  
       in  
       loop t1 t2 !res  
     in  
     List.iter add d;  
     List.map (!) !res  
   
 (*  
 This version explodes when dealing with  
    Any - [ t1? t2? t3? ... tn? ]  
 ==> need partitioning  
 *)  
   let get_aux d =  
     let line accu (left,right) =  
       let debug = List.length right = 28 in  
       let rec aux accu d1 d2 = function  
         | (t1,t2)::right ->  
             let accu =  
               let d1 = diff_t d1 t1 in  
               if is_empty d1 then accu else aux accu d1 d2 right in  
             let accu =  
               let d2 = diff_t d2 t2 in  
               if is_empty d2 then accu else aux accu d1 d2 right in  
             accu  
         | [] -> (d1,d2) :: accu  
       in  
       let (d1,d2) = cap_product left in  
       if (is_empty d1) || (is_empty d2) then accu else aux accu d1 d2 right  
     in  
     List.fold_left line [] d  
   
 (* Partitioning:  
   
 (t,s) - ((t1,s1) | (t2,s2) | ... | (tn,sn))  
 =  
 (t & t1, s - s1) | ... | (t & tn, s - sn) | (t - (t1|...|tn), s)  
   
 *)  
   
   let get_aux d =  
     let accu = ref [] in  
     let line (left,right) =  
       let (d1,d2) = cap_product left in  
       if (non_empty d1) && (non_empty d2) then  
         let right = List.map (fun (t1,t2) -> descr t1, descr t2) right in  
         let right = normal_aux right in  
         let resid1 = ref d1 in  
         let () =  
           List.iter  
             (fun (t1,t2) ->  
                let t1 = cap d1 t1 in  
                if (non_empty t1) then  
                  let () = resid1 := diff !resid1 t1 in  
                  let t2 = diff d2 t2 in  
                  if (non_empty t2) then accu := (t1,t2) :: !accu  
             ) right in  
         if non_empty !resid1 then accu := (!resid1, d2) :: !accu  
     in  
     List.iter line d;  
     !accu  
   
   let get d = get_aux d.times  
   
   let pi1 = List.fold_left (fun acc (t1,_) -> cup acc t1) empty  
   let pi2 = List.fold_left (fun acc (_,t2) -> cup acc t2) empty  
   
   let restrict_1 rects pi1 =  
     let aux accu (t1,t2) =  
       let t1 = cap t1 pi1 in if is_empty t1 then accu else (t1,t2)::accu in  
     List.fold_left aux [] rects  
   
   type normal = t  
   
   module Memo = Map.Make(struct  
                            type t = (node * node) Boolean.t  
                            let compare = compare end)  
   
   
   
   let memo = ref Memo.empty  
   let normal d =  
     let d = d.times in  
     try Memo.find d !memo  
     with  
         Not_found ->  
           let gd = get_aux d in  
           let n = normal_aux gd in  
           memo := Memo.add d n !memo;  
           n  
   
   let any = { empty with times = any.times }  
   let is_empty d = d = []  
 end  
   
746    
747  module Record =  module Record =
748  struct  struct
# Line 837  Line 916 
916          (fun (d1,d2) -> [(rec_normalize d1, rec_normalize d2)],[])          (fun (d1,d2) -> [(rec_normalize d1, rec_normalize d2)],[])
917          (Product.normal d)          (Product.normal d)
918      in      in
919        let xml =
920          map_sort
921            (fun (d1,d2) -> [(rec_normalize d1, rec_normalize d2)],[])
922            (Product.normal ~kind:`XML d)
923        in
924      let record =      let record =
925        map_sort        map_sort
926          (fun f -> map_sort (fun (l,(o,d)) -> (l,o,rec_normalize d)) f, [])          (fun f -> map_sort (fun (l,(o,d)) -> (l,o,rec_normalize d)) f, [])
927          (Record.get d)          (Record.get d)
928      in      in
929      define n { d with times = times; record = record };      define n { d with times = times; xml = xml; record = record };
930      n      n
931    
932  let normalize n =  let normalize n =

Legend:
Removed from v.109  
changed lines
  Added in v.110

CVS Admin">CVS Admin
ViewVC Help
Powered by ViewVC 1.1.5