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

Contents of /types/types.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 218 - (hide annotations)
Tue Jul 10 17:15:29 2007 UTC (5 years, 10 months ago) by abate
File size: 39284 byte(s)
[r2003-03-06 13:51:30 by cvscast] Empty log message

Original author: cvscast
Date: 2003-03-06 13:51:30+00:00
1 abate 1 open Recursive
2     open Printf
3    
4    
5 abate 75 let map_sort f l =
6     SortedList.from_list (List.map f l)
7 abate 1
8 abate 78 module HashedString =
9     struct
10     type t = string
11     let hash = Hashtbl.hash
12     let equal = (=)
13     end
14 abate 1
15 abate 78 module LabelPool = Pool.Make(HashedString)
16     module AtomPool = Pool.Make(HashedString)
17 abate 71
18 abate 78 type label = LabelPool.t
19     type atom = AtomPool.t
20 abate 71
21 abate 15 type const = Integer of Big_int.big_int | Atom of atom | Char of Chars.Unichar.t
22 abate 1
23 abate 110 type pair_kind = [ `Normal | `XML ]
24    
25 abate 1 module I = struct
26     type 'a t = {
27 abate 149 atoms : atom Atoms.t;
28 abate 1 ints : Intervals.t;
29 abate 149 chars : Chars.t;
30 abate 1 times : ('a * 'a) Boolean.t;
31 abate 110 xml : ('a * 'a) Boolean.t;
32 abate 1 arrow : ('a * 'a) Boolean.t;
33 abate 156 record: (bool * (label, (bool * 'a)) SortedMap.t) Boolean.t;
34 abate 1 }
35 abate 15
36 abate 1 let empty = {
37     times = Boolean.empty;
38 abate 110 xml = Boolean.empty;
39 abate 1 arrow = Boolean.empty;
40     record= Boolean.empty;
41     ints = Intervals.empty;
42     atoms = Atoms.empty;
43 abate 13 chars = Chars.empty;
44 abate 1 }
45 abate 119
46 abate 1 let any = {
47     times = Boolean.full;
48 abate 110 xml = Boolean.full;
49 abate 1 arrow = Boolean.full;
50     record= Boolean.full;
51 abate 15 ints = Intervals.any;
52 abate 18 atoms = Atoms.any;
53     chars = Chars.any;
54 abate 1 }
55 abate 119
56 abate 1
57 abate 52 let interval i = { empty with ints = i }
58 abate 1 let times x y = { empty with times = Boolean.atom (x,y) }
59 abate 110 let xml x y = { empty with xml = Boolean.atom (x,y) }
60 abate 1 let arrow x y = { empty with arrow = Boolean.atom (x,y) }
61 abate 156 let record label opt t =
62     { empty with record = Boolean.atom (true,[label,(opt,t)]) }
63 abate 159 let record' x =
64     { empty with record = Boolean.atom x }
65 abate 18 let atom a = { empty with atoms = a }
66     let char c = { empty with chars = c }
67 abate 1 let constant = function
68 abate 52 | Integer i -> interval (Intervals.atom i)
69 abate 18 | Atom a -> atom (Atoms.atom a)
70     | Char c -> char (Chars.atom c)
71 abate 1
72    
73 abate 8 let cup x y =
74 abate 69 if x = y then x else {
75 abate 8 times = Boolean.cup x.times y.times;
76 abate 110 xml = Boolean.cup x.xml y.xml;
77 abate 8 arrow = Boolean.cup x.arrow y.arrow;
78     record= Boolean.cup x.record y.record;
79     ints = Intervals.cup x.ints y.ints;
80     atoms = Atoms.cup x.atoms y.atoms;
81 abate 13 chars = Chars.cup x.chars y.chars;
82 abate 8 }
83    
84     let cap x y =
85 abate 69 if x = y then x else {
86 abate 8 times = Boolean.cap x.times y.times;
87 abate 110 xml = Boolean.cap x.xml y.xml;
88 abate 8 record= Boolean.cap x.record y.record;
89     arrow = Boolean.cap x.arrow y.arrow;
90     ints = Intervals.cap x.ints y.ints;
91     atoms = Atoms.cap x.atoms y.atoms;
92 abate 13 chars = Chars.cap x.chars y.chars;
93 abate 8 }
94    
95     let diff x y =
96 abate 69 if x = y then empty else {
97 abate 8 times = Boolean.diff x.times y.times;
98 abate 110 xml = Boolean.diff x.xml y.xml;
99 abate 8 arrow = Boolean.diff x.arrow y.arrow;
100     record= Boolean.diff x.record y.record;
101     ints = Intervals.diff x.ints y.ints;
102     atoms = Atoms.diff x.atoms y.atoms;
103 abate 13 chars = Chars.diff x.chars y.chars;
104 abate 8 }
105    
106 abate 1
107 abate 156 let rec equal_rec e r1 r2 =
108     match (r1,r2) with
109     | [],[] -> ()
110     | (l1,(o1,x1))::r1,(l2,(o2,x2))::r2 ->
111     if (l1 <> l2) || (o1 <> o2) then raise NotEqual;
112     e x1 x2; equal_rec e r1 r2
113     | _ -> raise NotEqual
114     (* check: faster to reverse the calls to e and to equal_rec ? *)
115    
116 abate 1 let equal e a b =
117     if a.atoms <> b.atoms then raise NotEqual;
118 abate 13 if a.chars <> b.chars then raise NotEqual;
119 abate 69 if a.ints <> b.ints then raise NotEqual;
120 abate 1 Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.times b.times;
121 abate 110 Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.xml b.xml;
122 abate 1 Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.arrow b.arrow;
123 abate 156 Boolean.equal (fun (o1,r1) (o2,r2) ->
124     if (o1 <> o2) then raise NotEqual;
125     equal_rec e r1 r2)
126     a.record b.record
127 abate 1
128     let map f a =
129     { times = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.times;
130 abate 110 xml = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.xml;
131 abate 1 arrow = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.arrow;
132 abate 156 record= Boolean.map (fun (o,r) ->
133     (o, List.map (fun (l,(o,x)) -> (l,(o,f x))) r))
134     a.record;
135 abate 1 ints = a.ints;
136     atoms = a.atoms;
137 abate 13 chars = a.chars;
138 abate 1 }
139    
140     let hash h a =
141 abate 69 Hashtbl.hash (map h a)
142     (*
143 abate 60 (Hashtbl.hash { (map h a) with ints = Intervals.empty })
144 abate 15 + (Intervals.hash a.ints)
145 abate 69 *)
146 abate 1
147     let iter f a =
148     ignore (map f a)
149 abate 16
150 abate 1 let deep = 4
151     end
152    
153 abate 110
154 abate 67 module Algebra = Recursive_noshare.Make(I)
155 abate 1 include I
156     include Algebra
157 abate 71 module DescrHash =
158     Hashtbl.Make(
159     struct
160     type t = descr
161     let hash = hash_descr
162     let equal = equal_descr
163     end
164     )
165 abate 1
166 abate 131 let print_descr = ref (fun _ _ -> assert false)
167    
168 abate 110 (*
169     let define n d = check d; define n d
170     *)
171    
172     let cons d =
173     let n = make () in
174     define n d;
175     internalize n
176    
177 abate 119 (*
178 abate 110 let any_rec = cons { empty with record = Boolean.full }
179     let any_node = make ();;
180     define any_node {
181     times = Boolean.full;
182     xml = Boolean.atom
183     (cons { empty with atoms = Atoms.any },
184     cons (times any_rec any_node));
185     arrow = Boolean.full;
186     record= Boolean.full;
187     ints = Intervals.any;
188     atoms = Atoms.any;
189     chars = Chars.any;
190     };;
191     internalize any_node;;
192     let any = descr any_node
193 abate 119 *)
194 abate 110
195     let neg x = diff any x
196    
197 abate 165 let any_node = cons any
198    
199 abate 156 (*
200 abate 110 let get_record r =
201     let add = SortedMap.add (fun (o1,t1) (o2,t2) -> (o1&&o2, cap t1 t2)) in
202     let line (p,n) =
203     let accu = List.fold_left
204     (fun accu (l,o,t) -> add l (o,descr t) accu) [] p in
205     List.fold_left
206     (fun accu (l,o,t) -> add l (not o,neg (descr t)) accu) accu n in
207     List.map line r
208 abate 156 *)
209 abate 110
210 abate 156 module LabelSet = Set.Make(LabelPool)
211 abate 110
212 abate 156 let get_record r =
213     let labs accu (_,r) =
214     List.fold_left (fun accu (l,_) -> LabelSet.add l accu) accu r in
215     let extend (opts,descrs) labs (o,r) =
216     let rec aux i labs r =
217     match labs with
218     | [] -> ()
219     | l1::labs ->
220     match r with
221     | (l2,(o,x))::r when l1 = l2 ->
222     descrs.(i) <- cap descrs.(i) (descr x);
223     opts.(i) <- opts.(i) && o;
224     aux (i+1) labs r
225     | r ->
226     if not o then descrs.(i) <- empty;
227     aux (i+1) labs r
228     in
229     aux 0 labs r;
230     o
231     in
232     let line (p,n) =
233     let labels =
234     List.fold_left labs (List.fold_left labs LabelSet.empty p) n in
235     let labels = LabelSet.elements labels in
236     let nlab = List.length labels in
237     let mk () = Array.create nlab true, Array.create nlab any in
238    
239     let pos = mk () in
240     let opos = List.fold_left
241     (fun accu x ->
242     (extend pos labels x) && accu)
243     true p in
244     let p = (opos, pos) in
245    
246     let n = List.map (fun x ->
247     let neg = mk () in
248     let o = extend neg labels x in
249     (o,neg)
250     ) n in
251     (labels,p,n)
252     in
253     List.map line r
254    
255    
256 abate 71 module DescrMap = Map.Make(struct type t = descr let compare = compare end)
257    
258 abate 1 let check d =
259     Boolean.check d.times;
260 abate 110 Boolean.check d.xml;
261 abate 1 Boolean.check d.arrow;
262     Boolean.check d.record;
263     ()
264    
265 abate 110
266    
267     (* Subtyping algorithm *)
268    
269     let diff_t d t = diff d (descr t)
270     let cap_t d t = cap d (descr t)
271     let cup_t d t = cup d (descr t)
272     let cap_product l =
273     List.fold_left
274     (fun (d1,d2) (t1,t2) -> (cap_t d1 t1, cap_t d2 t2))
275     (any,any)
276     l
277    
278    
279     let cup_product l =
280     List.fold_left
281     (fun (d1,d2) (t1,t2) -> (cup_t d1 t1, cup_t d2 t2))
282     (empty,empty)
283     l
284    
285 abate 156 let rec exists max f =
286     (max > 0) && (f (max - 1) || exists (max - 1) f)
287 abate 110
288 abate 156
289 abate 110 module Assumptions = Set.Make(struct type t = descr let compare = compare end)
290    
291     let memo = ref Assumptions.empty
292     let cache_false = ref Assumptions.empty
293    
294     exception NotEmpty
295    
296 abate 218 let trivially_empty d = d = empty
297    
298 abate 110 let rec empty_rec d =
299     if Assumptions.mem d !cache_false then false
300     else if Assumptions.mem d !memo then true
301     else if not (Intervals.is_empty d.ints) then false
302     else if not (Atoms.is_empty d.atoms) then false
303     else if not (Chars.is_empty d.chars) then false
304     else (
305     let backup = !memo in
306 abate 188 memo := Assumptions.add d backup;
307 abate 110 if
308     (empty_rec_times d.times) &&
309     (empty_rec_times d.xml) &&
310     (empty_rec_arrow d.arrow) &&
311     (empty_rec_record d.record)
312     then true
313     else (
314     memo := backup;
315     cache_false := Assumptions.add d !cache_false;
316     false
317     )
318     )
319    
320     and empty_rec_times c =
321     List.for_all empty_rec_times_aux c
322    
323     and empty_rec_times_aux (left,right) =
324     let rec aux accu1 accu2 = function
325     | (t1,t2)::right ->
326 abate 135 (* This avoids explosion with huge rhs (+/- degenerated partitioning)
327 abate 131 May be slower when List.length right is small; could optimize
328     this case... *)
329 abate 218 (* if empty_rec (cap_t accu1 t1) || empty_rec (cap_t accu2 t2) then*)
330     (* THIS IS NOT SOUND !!! *)
331     if trivially_empty (cap_t accu1 t1) ||
332     trivially_empty (cap_t accu2 t2) then
333 abate 131 aux accu1 accu2 right
334     else
335     let accu1' = diff_t accu1 t1 in
336     if not (empty_rec accu1') then aux accu1' accu2 right;
337     let accu2' = diff_t accu2 t2 in
338 abate 218 if not (empty_rec accu2') then aux accu1 accu2' right
339 abate 110 | [] -> raise NotEmpty
340     in
341     let (accu1,accu2) = cap_product left in
342     (empty_rec accu1) || (empty_rec accu2) ||
343     (* OPT? It does'nt seem so ... The hope was to return false quickly
344     for large right hand-side *)
345     (
346 abate 131 (* (if (List.length right > 2) then
347 abate 110 let (cup1,cup2) = cup_product right in
348     (empty_rec (diff accu1 cup1)) && (empty_rec (diff accu2 cup2))
349 abate 131 else true)
350     && *)
351 abate 110 (try aux accu1 accu2 right; true with NotEmpty -> false)
352     )
353    
354     and empty_rec_arrow c =
355     List.for_all empty_rec_arrow_aux c
356    
357     and empty_rec_arrow_aux (left,right) =
358     let single_right (s1,s2) =
359     let rec aux accu1 accu2 = function
360     | (t1,t2)::left ->
361     let accu1' = diff_t accu1 t1 in
362     if not (empty_rec accu1') then aux accu1 accu2 left;
363     let accu2' = cap_t accu2 t2 in
364     if not (empty_rec accu2') then aux accu1 accu2 left
365     | [] -> raise NotEmpty
366     in
367     let accu1 = descr s1 in
368     (empty_rec accu1) ||
369     (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)
370     in
371     List.exists single_right right
372    
373 abate 156 and empty_rec_record_aux (labels,(oleft,(left_opt,left)),rights) =
374     let rec aux = function
375     | [] -> raise NotEmpty
376     | (oright,(right_opt,right))::rights ->
377     let next =
378     (oleft && (not oright)) ||
379     exists (Array.length left)
380     (fun i ->
381     (not (left_opt.(i) && right_opt.(i))) &&
382     (empty_rec (cap left.(i) right.(i))))
383     in
384     if next then aux rights
385     else
386     for i = 0 to Array.length left - 1 do
387     let back = left.(i) in
388     let oback = left_opt.(i) in
389     let odi = oback && (not right_opt.(i)) in
390     let di = diff back right.(i) in
391     if odi || not (empty_rec di) then (
392     left.(i) <- diff back right.(i);
393     left_opt.(i) <- odi;
394     aux rights;
395     left.(i) <- back;
396     left_opt.(i) <- oback;
397     )
398     done
399     in
400     exists (Array.length left)
401     (fun i -> not left_opt.(i) && (empty_rec left.(i)))
402     ||
403     (try aux rights; true with NotEmpty -> false)
404    
405    
406 abate 110 and empty_rec_record c =
407 abate 156 (*
408 abate 110 let aux = List.exists (fun (_,(opt,t)) -> (not opt) && (empty_rec t)) in
409 abate 156 *)
410     List.for_all empty_rec_record_aux (get_record c)
411 abate 110
412     let is_empty d =
413 abate 131 (* Printf.eprintf "+"; flush stderr; *)
414 abate 110 let old = !memo in
415     let r = empty_rec d in
416 abate 186 if not r then memo := old
417     else if not (is_recurs_descr d) then memo := Assumptions.add d !memo;
418 abate 110 (* cache_false := Assumptions.empty; *)
419 abate 131 (* Printf.eprintf "-\n"; flush stderr; *)
420 abate 110 r
421    
422     let non_empty d =
423     not (is_empty d)
424    
425     let subtype d1 d2 =
426     is_empty (diff d1 d2)
427    
428     module Product =
429     struct
430     type t = (descr * descr) list
431    
432     let other ?(kind=`Normal) d =
433     match kind with
434     | `Normal -> { d with times = empty.times }
435     | `XML -> { d with xml = empty.xml }
436    
437     let is_product ?kind d = is_empty (other ?kind d)
438    
439     let need_second = function _::_::_ -> true | _ -> false
440    
441     let normal_aux d =
442     let res = ref [] in
443    
444     let add (t1,t2) =
445     let rec loop t1 t2 = function
446     | [] -> res := (ref (t1,t2)) :: !res
447     | ({contents = (d1,d2)} as r)::l ->
448     (*OPT*)
449     if d1 = t1 then r := (d1,cup d2 t2) else
450    
451     let i = cap t1 d1 in
452     if is_empty i then loop t1 t2 l
453     else (
454     r := (i, cup t2 d2);
455     let k = diff d1 t1 in
456     if non_empty k then res := (ref (k,d2)) :: !res;
457    
458     let j = diff t1 d1 in
459     if non_empty j then loop j t2 l
460     )
461     in
462     loop t1 t2 !res
463     in
464     List.iter add d;
465     List.map (!) !res
466    
467 abate 1 (*
468 abate 110 This version explodes when dealing with
469     Any - [ t1? t2? t3? ... tn? ]
470     ==> need partitioning
471 abate 1 *)
472 abate 110 let get_aux d =
473     let line accu (left,right) =
474     let rec aux accu d1 d2 = function
475     | (t1,t2)::right ->
476     let accu =
477     let d1 = diff_t d1 t1 in
478     if is_empty d1 then accu else aux accu d1 d2 right in
479     let accu =
480     let d2 = diff_t d2 t2 in
481     if is_empty d2 then accu else aux accu d1 d2 right in
482     accu
483     | [] -> (d1,d2) :: accu
484     in
485     let (d1,d2) = cap_product left in
486     if (is_empty d1) || (is_empty d2) then accu else aux accu d1 d2 right
487     in
488     List.fold_left line [] d
489 abate 1
490 abate 110 (* Partitioning:
491 abate 1
492 abate 110 (t,s) - ((t1,s1) | (t2,s2) | ... | (tn,sn))
493     =
494     (t & t1, s - s1) | ... | (t & tn, s - sn) | (t - (t1|...|tn), s)
495 abate 1
496 abate 110 *)
497     let get_aux d =
498     let accu = ref [] in
499     let line (left,right) =
500     let (d1,d2) = cap_product left in
501     if (non_empty d1) && (non_empty d2) then
502     let right = List.map (fun (t1,t2) -> descr t1, descr t2) right in
503     let right = normal_aux right in
504     let resid1 = ref d1 in
505     let () =
506     List.iter
507     (fun (t1,t2) ->
508     let t1 = cap d1 t1 in
509     if (non_empty t1) then
510     let () = resid1 := diff !resid1 t1 in
511     let t2 = diff d2 t2 in
512     if (non_empty t2) then accu := (t1,t2) :: !accu
513     ) right in
514     if non_empty !resid1 then accu := (!resid1, d2) :: !accu
515     in
516     List.iter line d;
517     !accu
518 abate 169 (* Maybe, can improve this function with:
519     (t,s) \ (t1,s1) = (t&t',s\s') | (t\t',s),
520     don't call normal_aux *)
521 abate 126
522 abate 218
523 abate 110 let get ?(kind=`Normal) d =
524     match kind with
525     | `Normal -> get_aux d.times
526     | `XML -> get_aux d.xml
527    
528     let pi1 = List.fold_left (fun acc (t1,_) -> cup acc t1) empty
529     let pi2 = List.fold_left (fun acc (_,t2) -> cup acc t2) empty
530    
531     let restrict_1 rects pi1 =
532     let aux accu (t1,t2) =
533     let t1 = cap t1 pi1 in if is_empty t1 then accu else (t1,t2)::accu in
534     List.fold_left aux [] rects
535    
536     type normal = t
537    
538     module Memo = Map.Make(struct
539     type t = (node * node) Boolean.t
540     let compare = compare end)
541    
542    
543    
544     let memo = ref Memo.empty
545     let normal ?(kind=`Normal) d =
546     let d = match kind with `Normal -> d.times | `XML -> d.xml in
547     try Memo.find d !memo
548     with
549     Not_found ->
550     let gd = get_aux d in
551     let n = normal_aux gd in
552 abate 169 (* Could optimize this call to normal_aux because one already
553     know that each line is normalized ... *)
554 abate 110 memo := Memo.add d n !memo;
555     n
556    
557     let any = { empty with times = any.times }
558     and any_xml = { empty with xml = any.xml }
559     let is_empty d = d = []
560     end
561    
562 abate 71 module Print =
563     struct
564 abate 110 let rec print_union ppf = function
565     | [] -> Format.fprintf ppf "Empty"
566     | [h] -> h ppf
567     | h::t -> Format.fprintf ppf "@[%t |@ %a@]" h print_union t
568    
569 abate 78 let print_atom ppf a =
570     Format.fprintf ppf "`%s" (AtomPool.value a)
571 abate 71
572 abate 110 let print_tag ppf a =
573     match Atoms.is_atom a with
574     | Some a -> Format.fprintf ppf "%s" (AtomPool.value a)
575     | None ->
576     Format.fprintf ppf "(%a)"
577     print_union
578     (Atoms.print "Atom" print_atom a)
579    
580 abate 71 let print_const ppf = function
581     | Integer i -> Format.fprintf ppf "%s" (Big_int.string_of_big_int i)
582     | Atom a -> print_atom ppf a
583     | Char c -> Chars.Unichar.print ppf c
584    
585 abate 95 let named = State.ref "Types.Printf.named" DescrMap.empty
586     let register_global name d =
587     named := DescrMap.add d name !named
588 abate 71
589     let marks = DescrHash.create 63
590     let wh = ref []
591     let count_name = ref 0
592     let name () =
593     incr count_name;
594     "X" ^ (string_of_int !count_name)
595     (* TODO:
596     check that these generated names does not conflict with declared types *)
597    
598     let bool_iter f b =
599     List.iter (fun (p,n) -> List.iter f p; List.iter f n) b
600    
601     let trivial b = b = Boolean.empty || b = Boolean.full
602    
603     let worth_abbrev d =
604     not (trivial d.times && trivial d.arrow && trivial d.record)
605    
606     let rec mark n = mark_descr (descr n)
607     and mark_descr d =
608 abate 95 if not (DescrMap.mem d !named) then
609 abate 71 try
610     let r = DescrHash.find marks d in
611     if (!r = None) && (worth_abbrev d) then
612     let na = name () in
613     r := Some na;
614     wh := (na,d) :: !wh
615     with Not_found ->
616     DescrHash.add marks d (ref None);
617     bool_iter (fun (n1,n2) -> mark n1; mark n2) d.times;
618 abate 111 bool_iter
619 abate 156 (fun (n1,n2) -> mark n1; mark n2
620     (*
621 abate 111 List.iter
622     (fun (d1,d2) ->
623     mark_descr d2;
624 abate 156 bool_iter
625     (fun (o,l) -> List.iter (fun (l,(o,n)) -> mark n) l)
626     d1.record
627 abate 111 let l = get_record d1.record in
628 abate 156 List.iter (fun labs,(_,(_,p)),ns ->
629     Array.iter mark_descr p;
630     List.iter (fun (_,(_,n)) ->
631     Array.iter mark_descr n) ns
632     ) l
633 abate 111 )
634     (Product.normal (descr n2))
635 abate 156 *)
636 abate 111 ) d.xml;
637 abate 71 bool_iter (fun (n1,n2) -> mark n1; mark n2) d.arrow;
638 abate 156 bool_iter (fun (o,l) -> List.iter (fun (l,(o,n)) -> mark n) l) d.record
639 abate 71
640    
641     let rec print ppf n = print_descr ppf (descr n)
642     and print_descr ppf d =
643     try
644 abate 95 let name = DescrMap.find d !named in
645 abate 71 Format.fprintf ppf "%s" name
646     with Not_found ->
647     try
648     match !(DescrHash.find marks d) with
649     | Some n -> Format.fprintf ppf "%s" n
650     | None -> real_print_descr ppf d
651     with
652 abate 110 Not_found -> assert false
653 abate 71 and real_print_descr ppf d =
654     if d = any then Format.fprintf ppf "Any" else
655     print_union ppf
656     (Intervals.print d.ints @
657     Chars.print d.chars @
658     Atoms.print "Atom" print_atom d.atoms @
659     Boolean.print "Pair" print_times d.times @
660 abate 110 Boolean.print "XML" print_xml d.xml @
661 abate 71 Boolean.print "Arrow" print_arrow d.arrow @
662     Boolean.print "Record" print_record d.record
663     )
664     and print_times ppf (t1,t2) =
665     Format.fprintf ppf "@[(%a,%a)@]" print t1 print t2
666 abate 110 and print_xml ppf (t1,t2) =
667 abate 156 Format.fprintf ppf "@[XML(%a,%a)@]" print t1 print t2
668     (*
669 abate 110 let l = Product.normal (descr t2) in
670     let l = List.map
671     (fun (d1,d2) ppf ->
672     Format.fprintf ppf "@[<><%a%a>%a@]"
673     print_tag (descr t1).atoms
674     print_attribs d1.record
675     print_descr d2) l
676     in
677     print_union ppf l
678 abate 156 *)
679 abate 71 and print_arrow ppf (t1,t2) =
680     Format.fprintf ppf "@[(%a -> %a)@]" print t1 print t2
681 abate 156 and print_record ppf (o,r) =
682     let o = if o then "" else "|" in
683     Format.fprintf ppf "@[{%s" o;
684     let first = ref true in
685     List.iter (fun (l,(o,t)) ->
686 abate 159 let sep = if !first then (first := false; "") else ";" in
687     Format.fprintf ppf "%s@ @[%s =%s@] %a" sep
688 abate 156 (LabelPool.value l) (if o then "?" else "") print t
689     ) r;
690     Format.fprintf ppf " %s}@]" o
691     (*
692 abate 110 and print_attribs ppf r =
693     let l = get_record r in
694     if l <> [ [] ] then
695     let l = List.map
696     (fun att ppf ->
697     let first = ref true in
698     Format.fprintf ppf "{" ;
699     List.iter (fun (l,(o,d)) ->
700     Format.fprintf ppf "%s%s=%s%a"
701     (if !first then "" else " ")
702     (LabelPool.value l) (if o then "?" else "")
703     print_descr d;
704     first := false
705     ) att;
706     Format.fprintf ppf "}"
707     ) l in
708     print_union ppf l
709 abate 156 *)
710 abate 71
711    
712     let end_print ppf =
713     (match List.rev !wh with
714     | [] -> ()
715     | (na,d)::t ->
716     Format.fprintf ppf " where@ @[%s = %a" na real_print_descr d;
717     List.iter
718     (fun (na,d) ->
719     Format.fprintf ppf " and@ %s = %a" na real_print_descr d)
720     t;
721     Format.fprintf ppf "@]"
722     );
723     Format.fprintf ppf "@]";
724     count_name := 0;
725     wh := [];
726     DescrHash.clear marks
727    
728     let print_descr ppf d =
729     mark_descr d;
730     Format.fprintf ppf "@[%a" print_descr d;
731     end_print ppf
732    
733     let print ppf n = print_descr ppf (descr n)
734    
735     end
736    
737 abate 131 let () = print_descr := Print.print_descr
738 abate 71
739 abate 1 module Positive =
740     struct
741     type rhs = [ `Type of descr | `Cup of v list | `Times of v * v ]
742     and v = { mutable def : rhs; mutable node : node option }
743    
744    
745     let rec make_descr seen v =
746     if List.memq v seen then empty
747     else
748     let seen = v :: seen in
749     match v.def with
750     | `Type d -> d
751     | `Cup vl ->
752     List.fold_left (fun acc v -> cup acc (make_descr seen v)) empty vl
753     | `Times (v1,v2) -> times (make_node v1) (make_node v2)
754    
755     and make_node v =
756     match v.node with
757     | Some n -> n
758     | None ->
759     let n = make () in
760     v.node <- Some n;
761     let d = make_descr [] v in
762     define n d;
763     n
764    
765     let forward () = { def = `Cup []; node = None }
766     let def v d = v.def <- d
767     let cons d = let v = forward () in def v d; v
768     let ty d = cons (`Type d)
769     let cup vl = cons (`Cup vl)
770     let times d1 d2 = cons (`Times (d1,d2))
771     let define v1 v2 = def v1 (`Cup [v2])
772    
773     let solve v = internalize (make_node v)
774     end
775    
776    
777    
778    
779     (* Sample value *)
780     module Sample =
781     struct
782    
783 abate 158
784 abate 1 let rec find f = function
785     | [] -> raise Not_found
786     | x::r -> try f x with Not_found -> find f r
787    
788     type t =
789 abate 15 | Int of Big_int.big_int
790 abate 1 | Atom of atom
791 abate 13 | Char of Chars.Unichar.t
792 abate 110 | Pair of (t * t)
793     | Xml of (t * t)
794 abate 1 | Record of (label * t) list
795     | Fun of (node * node) list
796 abate 156 | Other
797 abate 158 exception FoundSampleRecord of (label * t) list
798 abate 1
799     let rec sample_rec memo d =
800     if (Assumptions.mem d memo) || (is_empty d) then raise Not_found
801     else
802     try Int (Intervals.sample d.ints) with Not_found ->
803 abate 78 try Atom (Atoms.sample (fun _ -> AtomPool.dummy_min) d.atoms) with
804     Not_found ->
805     (* Here: could create a fresh atom ... *)
806 abate 13 try Char (Chars.sample d.chars) with Not_found ->
807 abate 1 try sample_rec_arrow d.arrow with Not_found ->
808    
809     let memo = Assumptions.add d memo in
810 abate 110 try Pair (sample_rec_times memo d.times) with Not_found ->
811     try Xml (sample_rec_times memo d.xml) with Not_found ->
812 abate 1 try sample_rec_record memo d.record with Not_found ->
813     raise Not_found
814    
815    
816     and sample_rec_times memo c =
817     find (sample_rec_times_aux memo) c
818    
819     and sample_rec_times_aux memo (left,right) =
820     let rec aux accu1 accu2 = function
821     | (t1,t2)::right ->
822 abate 158 (*TODO: check: is this correct ? non_empty could return true
823     but because of coinduction, the call to aux may raise Not_found, no ? *)
824 abate 1 let accu1' = diff_t accu1 t1 in
825     if non_empty accu1' then aux accu1' accu2 right else
826     let accu2' = diff_t accu2 t2 in
827     if non_empty accu2' then aux accu1 accu2' right else
828     raise Not_found
829 abate 110 | [] -> (sample_rec memo accu1, sample_rec memo accu2)
830 abate 1 in
831     let (accu1,accu2) = cap_product left in
832     if (is_empty accu1) || (is_empty accu2) then raise Not_found;
833     aux accu1 accu2 right
834    
835     and sample_rec_arrow c =
836     find sample_rec_arrow_aux c
837    
838 abate 10 and check_empty_simple_arrow_line left (s1,s2) =
839     let rec aux accu1 accu2 = function
840     | (t1,t2)::left ->
841     let accu1' = diff_t accu1 t1 in
842     if non_empty accu1' then aux accu1 accu2 left;
843     let accu2' = cap_t accu2 t2 in
844     if non_empty accu2' then aux accu1 accu2 left
845     | [] -> raise NotEmpty
846     in
847     let accu1 = descr s1 in
848     (is_empty accu1) ||
849     (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)
850    
851     and check_empty_arrow_line left right =
852     List.exists (check_empty_simple_arrow_line left) right
853    
854 abate 1 and sample_rec_arrow_aux (left,right) =
855 abate 10 if (check_empty_arrow_line left right) then raise Not_found
856 abate 1 else Fun left
857    
858    
859     and sample_rec_record memo c =
860     Record (find (sample_rec_record_aux memo) (get_record c))
861    
862 abate 158 and sample_rec_record_aux memo (labels,(oleft,(left_opt,left)),rights) =
863     let rec aux = function
864     | [] ->
865     let l = ref labels and fields = ref [] in
866     for i = 0 to Array.length left - 1 do
867     if not left_opt.(i) then
868     fields := (List.hd !l, sample_rec memo left.(i))::!fields;
869     l := List.tl !l
870     done;
871     raise (FoundSampleRecord (List.rev !fields))
872     | (oright,(right_opt,right))::rights ->
873     let next = (oleft && (not oright)) in
874     if next then aux rights
875     else
876     for i = 0 to Array.length left - 1 do
877     let back = left.(i) in
878     let oback = left_opt.(i) in
879     let odi = oback && (not right_opt.(i)) in
880     let di = diff back right.(i) in
881     if odi || not (is_empty di) then (
882     left.(i) <- diff back right.(i);
883     left_opt.(i) <- odi;
884     aux rights;
885     left.(i) <- back;
886     left_opt.(i) <- oback;
887     )
888     done
889     in
890     if exists (Array.length left)
891     (fun i -> not left_opt.(i) && (is_empty left.(i))) then raise Not_found;
892     try aux rights; raise Not_found
893     with FoundSampleRecord r -> r
894 abate 1
895 abate 158
896    
897    
898    
899 abate 156 let get x = try sample_rec Assumptions.empty x with Not_found -> Other
900 abate 10
901 abate 71 let rec print_sep f sep ppf = function
902     | [] -> ()
903     | [x] -> f ppf x
904     | x::rem -> f ppf x; Format.fprintf ppf "%s" sep; print_sep f sep ppf rem
905    
906    
907     let rec print ppf = function
908     | Int i -> Format.fprintf ppf "%s" (Big_int.string_of_big_int i)
909 abate 78 | Atom a ->
910     if a = LabelPool.dummy_min then
911     Format.fprintf ppf "(almost any atom)"
912     else
913     Format.fprintf ppf "`%s" (AtomPool.value a)
914 abate 71 | Char c -> Chars.Unichar.print ppf c
915     | Pair (x1,x2) -> Format.fprintf ppf "(%a,%a)" print x1 print x2
916 abate 110 | Xml (x1,x2) -> Format.fprintf ppf "XML(%a,%a)" print x1 print x2
917 abate 71 | Record r ->
918     Format.fprintf ppf "{ %a }"
919     (print_sep
920     (fun ppf (l,x) ->
921     Format.fprintf ppf "%s = %a"
922 abate 78 (LabelPool.value l)
923 abate 71 print x
924     )
925     " ; "
926     ) r
927     | Fun iface ->
928     Format.fprintf ppf "(fun ( %a ) x -> ...)"
929     (print_sep
930     (fun ppf (t1,t2) ->
931     Format.fprintf ppf "%a -> %a; "
932     Print.print t1 Print.print t2
933     )
934     " ; "
935     ) iface
936 abate 156 | Other ->
937     Format.fprintf ppf "[cannot determine value]"
938 abate 1 end
939    
940    
941    
942     module Record =
943     struct
944 abate 156 type atom = bool * (label, (bool * node)) SortedMap.t
945     type t = atom Boolean.t
946    
947     let get d = d.record
948    
949 abate 160 module T = struct
950     type t = descr
951     let any = any
952     let cap = cap
953     let cup = cup
954     let diff = diff
955     let empty = is_empty
956     end
957     module R = struct
958     (*Note: Boolean.cap,cup,diff would be ok,
959     but we add here the simplification rules:
960     { } & r --> r ; { } | r -> { }
961     r \ { } --> Empty *)
962    
963     type t = atom Boolean.t
964     let any = Boolean.full
965     let cap = Boolean.cap
966     let cup = Boolean.cup
967     let diff = Boolean.diff
968     let empty x = is_empty { empty with record = x }
969     end
970     module TR = Normal.Make(T)(R)
971    
972     let atom = function
973     | (true,[]) -> Boolean.full
974     | (o,l) -> Boolean.atom (o,l)
975    
976 abate 165 let somefield_possible t =
977     not (R.empty (R.diff t (Boolean.atom (false,[]))))
978    
979     let nofield_possible t =
980     not (R.empty (R.cap t (Boolean.atom (false,[]))))
981    
982 abate 156 let restrict_label_absent t l =
983     Boolean.compute_bool
984 abate 188 (fun ((o,r) as x) ->
985 abate 156 try
986     let (lo,_) = List.assoc l r in
987 abate 160 if lo then atom (o,SortedMap.diff r [l])
988 abate 156 else Boolean.empty
989     with Not_found -> Boolean.atom x
990     )
991     t
992    
993     let restrict_field t l d =
994     (* Is it correct ? Do we need to keep track of "first component"
995     (value of l) as in label_present, then filter at the end ... ? *)
996     Boolean.compute_bool
997 abate 188 (fun ((o,r) as x) ->
998 abate 156 try
999     let (lo,lt) = List.assoc l r in
1000     if (not lo) && (is_empty (cap d (descr lt))) then Boolean.empty
1001 abate 160 else atom (o, SortedMap.diff r [l])
1002 abate 156 with Not_found ->
1003     if o then Boolean.atom x else Boolean.empty
1004     )
1005     t
1006    
1007    
1008    
1009     let label_present (t:t) l : (descr * t) list =
1010     let x =
1011     Boolean.compute_bool
1012 abate 188 (fun ((o,r) as x) ->
1013 abate 156 try
1014     let (_,lt) = List.assoc l r in
1015 abate 160 Boolean.atom (descr lt, atom (o, SortedMap.diff r [l]))
1016 abate 156 with Not_found ->
1017     if o then Boolean.atom (any, Boolean.atom x) else Boolean.empty
1018     )
1019     t
1020     in
1021     TR.boolean x
1022    
1023     let restrict_label_present t l =
1024 abate 165 Boolean.compute_bool
1025 abate 188 (fun ((o,r) as x) ->
1026 abate 165 try
1027     Boolean.atom (o, SortedMap.change_exists l (fun (_,lt) -> (false,lt)) r)
1028     with Not_found ->
1029     if o then Boolean.atom
1030     (true, SortedMap.union_disj [l, (false,any_node)] r)
1031     else Boolean.empty
1032     )
1033     t
1034 abate 156
1035     let project_field t l =
1036     let r = label_present t l in
1037     List.fold_left (fun accu (d,_) -> cup accu d) empty r
1038    
1039     let project t l =
1040     let t = get t in
1041 abate 160 let r = label_present t l in
1042     if r = [] then raise Not_found else
1043     List.fold_left (fun accu (d,_) -> cup accu d) empty r
1044 abate 156
1045     type normal =
1046     [ `Success
1047     | `Fail
1048 abate 159 | `NoField
1049     | `SomeField
1050 abate 156 | `Label of label * (descr * normal) list * normal ]
1051    
1052     let first_label t =
1053     let min = ref None in
1054     let lab l = match !min with
1055     | Some l' when l >= l' -> ()
1056     | _ -> min := Some l in
1057     let aux = function
1058     | _,[] -> ()
1059     | _,(l,_)::_ -> lab l in
1060     Boolean.iter aux t;
1061     match !min with
1062     | Some l -> `Label l
1063     | None ->
1064     let n =
1065     Boolean.compute
1066     ~empty:0
1067     ~full:3
1068     ~cup:(lor)
1069     ~cap:(land)
1070     ~diff:(fun a b -> a land lnot b)
1071     ~atom:(function (true,[]) -> 3 | (false,[]) -> 1 | _ -> assert false)
1072     t in
1073     match n with
1074     | 0 -> `Fail
1075     | 1 -> `NoField
1076     | 2 -> `SomeField
1077     | _ -> `Success
1078    
1079    
1080 abate 160 let normal' t l =
1081     let present = label_present t l
1082     and absent = restrict_label_absent t l in
1083     List.map (fun (d,t) -> d,t) present, absent
1084    
1085 abate 156 let rec normal_aux t =
1086     match first_label t with
1087     | `Label l ->
1088     let present = label_present t l
1089     and absent = restrict_label_absent t l in
1090     `Label (l, List.map (fun (d,t) -> d, normal_aux t) present,
1091     normal_aux absent)
1092     | `Fail -> `Fail
1093     | `Success -> `Success
1094 abate 159 | `NoField -> `NoField
1095     | `SomeField -> `SomeField
1096 abate 156
1097     let normal t = normal_aux (get t)
1098    
1099    
1100    
1101     let descr x = { empty with record = x }
1102     let is_empty x = is_empty (descr x)
1103     (*
1104    
1105 abate 1 type t = (label, (bool * descr)) SortedMap.t list
1106    
1107     let get d =
1108     let line r = List.for_all (fun (l,(o,d)) -> o || non_empty d) r in
1109     List.filter line (get_record d.record)
1110    
1111     let restrict_label_present t l =
1112 abate 29 let restr = function
1113     | (true, d) -> if non_empty d then (false,d) else raise Exit
1114     | x -> x in
1115     let aux accu r =
1116     try SortedMap.change l restr (false,any) r :: accu
1117     with Exit -> accu in
1118     List.fold_left aux [] t
1119 abate 1
1120     let restrict_label_absent t l =
1121     let restr = function (true, _) -> (true,empty) | _ -> raise Exit in
1122     let aux accu r =
1123     try SortedMap.change l restr (true,empty) r :: accu
1124     with Exit -> accu in
1125     List.fold_left aux [] t
1126    
1127     let restrict_field t l d =
1128     let restr (_,d1) =
1129     let d1 = cap d d1 in
1130     if is_empty d1 then raise Exit else (false,d1) in
1131     let aux accu r =
1132     try SortedMap.change l restr (false,d) r :: accu
1133     with Exit -> accu in
1134     List.fold_left aux [] t
1135    
1136     let project_field t l =
1137     let aux accu x =
1138     match List.assoc l x with
1139     | (false,t) -> cup accu t
1140     | _ -> raise Not_found
1141     in
1142     List.fold_left aux empty t
1143    
1144 abate 29 let project d l =
1145     project_field (get_record d.record) l
1146    
1147 abate 1 type normal =
1148     [ `Success
1149     | `Fail
1150     | `Label of label * (descr * normal) list * normal ]
1151    
1152     let rec merge_record n r =
1153     match (n, r) with
1154     | (`Success, _) | (_, []) -> `Success
1155     | (`Fail, r) ->
1156 abate 75 let aux (l,(o,t)) n =
1157     `Label (l, [t,n], if o then n else `Fail) in
1158 abate 1 List.fold_right aux r `Success
1159     | (`Label (l1,present,absent), (l2,(o,t2))::r') ->
1160     if (l1 < l2) then
1161     let pr = List.map (fun (t,x) -> (t, merge_record x r)) present in
1162 abate 75 let t = List.fold_left (fun a (t,_) -> diff a t) any present in
1163     let pr =
1164     if non_empty t then (t, merge_record `Fail r) :: pr
1165     else pr in
1166 abate 1 `Label (l1,pr,merge_record absent r)
1167     else if (l2 < l1) then
1168     let n' = merge_record n r' in
1169     `Label (l2, [t2, n'], if o then n' else n)
1170     else
1171     let res = ref [] in
1172     let aux a (t,x) =
1173     (let t = diff t t2 in
1174     if non_empty t then res := (t,x) :: !res);
1175     (let t = cap t t2 in
1176     if non_empty t then res := (t, merge_record x r') :: !res);
1177     diff a t
1178     in
1179     let t2 = List.fold_left aux t2 present in
1180     let () =
1181     if non_empty t2 then
1182     res := (t2, merge_record `Fail r') :: !res in
1183     let abs = if o then merge_record absent r' else absent in
1184     `Label (l1, !res, abs)
1185    
1186 abate 75 module Unify = Map.Make(struct type t = normal let compare = compare end)
1187 abate 1
1188 abate 75 let repository = ref Unify.empty
1189    
1190     let rec canonize = function
1191     | `Label (l,pr,ab) as x ->
1192     (try Unify.find x !repository
1193     with Not_found ->
1194     let pr = List.map (fun (t,n) -> canonize n,t) pr in
1195     let pr = SortedMap.from_list cup pr in
1196     let pr = List.map (fun (n,t) -> (t,n)) pr in
1197     let x = `Label (l, pr, canonize ab) in
1198     try Unify.find x !repository
1199     with Not_found -> repository := Unify.add x x !repository; x
1200     )
1201     | x -> x
1202    
1203 abate 1 let normal d =
1204 abate 75 let r = canonize (List.fold_left merge_record `Fail (get d)) in
1205     repository := Unify.empty;
1206     r
1207 abate 1
1208 abate 75 type normal' =
1209     [ `Success
1210     | `Label of label * (descr * descr) list * descr option ] option
1211 abate 1
1212 abate 75 (* NOTE: this function relies on the fact that generic order
1213     makes smallest labels appear first *)
1214    
1215     let first_label d =
1216     let d = d.record in
1217     let min = ref None in
1218     let lab (l,o,t) = match !min with
1219     | Some l' when l >= l' -> ()
1220     | _ -> if o && (descr t = any) then () else min := Some l in
1221     let line (p,n) =
1222     (match p with f::_ -> lab f | _ -> ());
1223     (match n with f::_ -> lab f | _ -> ()) in
1224     List.iter line d;
1225     match !min with
1226     | None -> if d = [] then `Empty else `Any
1227     | Some l -> `Label l
1228    
1229     let normal' (d : descr) l =
1230     let ab = ref empty in
1231     let rec extract f = function
1232     | (l',o,t) :: rem when l = l' ->
1233     f o (descr t); extract f rem
1234     | x :: rem -> x :: (extract f rem)
1235     | [] -> [] in
1236     let line (p,n) =
1237     let ao = ref true and ad = ref any in
1238     let p =
1239     extract (fun o d -> ao := !ao && o; ad := cap !ad d) p
1240     and n =
1241     extract (fun o d -> ao := !ao && not o; ad := diff !ad d) n
1242     in
1243     (* Note: p and n are still sorted *)
1244     let d = { empty with record = [(p,n)] } in
1245     if !ao then ab := cup d !ab;
1246     (!ad, d) in
1247     let pr = List.map line d.record in
1248     let pr = Product.normal_aux pr in
1249     let ab = if is_empty !ab then None else Some !ab in
1250     (pr, ab)
1251    
1252 abate 156 *)
1253 abate 75
1254 abate 1 let any = { empty with record = any.record }
1255 abate 156 (*
1256 abate 1 let is_empty d = d = []
1257 abate 75 let descr l =
1258     let line l = map_sort (fun (l,(o,d)) -> (l,o,cons d)) l, [] in
1259     { empty with record = map_sort line l }
1260 abate 156 *)
1261 abate 1 end
1262    
1263    
1264 abate 29
1265 abate 71 let memo_normalize = ref DescrMap.empty
1266 abate 1
1267    
1268     let rec rec_normalize d =
1269 abate 71 try DescrMap.find d !memo_normalize
1270 abate 1 with Not_found ->
1271     let n = make () in
1272 abate 71 memo_normalize := DescrMap.add d n !memo_normalize;
1273 abate 1 let times =
1274     map_sort
1275     (fun (d1,d2) -> [(rec_normalize d1, rec_normalize d2)],[])
1276     (Product.normal d)
1277     in
1278 abate 110 let xml =
1279     map_sort
1280     (fun (d1,d2) -> [(rec_normalize d1, rec_normalize d2)],[])
1281     (Product.normal ~kind:`XML d)
1282     in
1283 abate 156 let record = d.record
1284     (*
1285 abate 1 map_sort
1286     (fun f -> map_sort (fun (l,(o,d)) -> (l,o,rec_normalize d)) f, [])
1287     (Record.get d)
1288 abate 156 *)
1289 abate 1 in
1290 abate 110 define n { d with times = times; xml = xml; record = record };
1291 abate 1 n
1292    
1293     let normalize n =
1294 abate 29 descr (internalize (rec_normalize n))
1295 abate 6
1296 abate 11 module Arrow =
1297     struct
1298 abate 19 let check_simple left s1 s2 =
1299     let rec aux accu1 accu2 = function
1300     | (t1,t2)::left ->
1301     let accu1' = diff_t accu1 t1 in
1302 abate 45 if non_empty accu1' then aux accu1 accu2 left;
1303 abate 19 let accu2' = cap_t accu2 t2 in
1304 abate 45 if non_empty accu2' then aux accu1 accu2 left
1305 abate 19 | [] -> raise NotEmpty
1306     in
1307     let accu1 = descr s1 in
1308     (is_empty accu1) ||
1309     (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)
1310    
1311     let check_strenghten t s =
1312     let left = match t.arrow with [ (p,[]) ] -> p | _ -> assert false in
1313     let rec aux = function
1314     | [] -> raise Not_found
1315     | (p,n) :: rem ->
1316     if (List.for_all (fun (a,b) -> check_simple left a b) p) &&
1317     (List.for_all (fun (a,b) -> not (check_simple left a b)) n) then
1318     { empty with arrow = [ (SortedList.cup left p, n) ] }
1319     else aux rem
1320     in
1321     aux s.arrow
1322    
1323 abate 45 let check_simple_iface left s1 s2 =
1324     let rec aux accu1 accu2 = function
1325     | (t1,t2)::left ->
1326     let accu1' = diff accu1 t1 in
1327     if non_empty accu1' then aux accu1 accu2 left;
1328     let accu2' = cap accu2 t2 in
1329     if non_empty accu2' then aux accu1 accu2 left
1330     | [] -> raise NotEmpty
1331     in
1332     let accu1 = descr s1 in
1333     (is_empty accu1) ||
1334     (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)
1335    
1336     let check_iface iface s =
1337     let rec aux = function
1338     | [] -> false
1339     | (p,n) :: rem ->
1340     ((List.for_all (fun (a,b) -> check_simple_iface iface a b) p) &&
1341     (List.for_all (fun (a,b) -> not (check_simple_iface iface a b)) n))
1342     || (aux rem)
1343     in
1344     aux s.arrow
1345    
1346 abate 11 type t = descr * (descr * descr) list list
1347    
1348     let get t =
1349     List.fold_left
1350     (fun ((dom,arr) as accu) (left,right) ->
1351     if Sample.check_empty_arrow_line left right
1352     then accu
1353     else (
1354     let left =
1355     List.map
1356     (fun (t,s) -> (descr t, descr s)) left in
1357     let d = List.fold_left (fun d (t,_) -> cup d t) empty left in
1358     (cap dom d, left :: arr)
1359     )
1360     )
1361     (any, [])
1362     t.arrow
1363    
1364     let domain (dom,_) = dom
1365    
1366     let apply_simple t result left =
1367     let rec aux result accu1 accu2 = function
1368     | (t1,s1)::left ->
1369     let result =
1370     let accu1 = diff accu1 t1 in
1371     if non_empty accu1 then aux result accu1 accu2 left
1372     else result in
1373     let result =
1374     let accu2 = cap accu2 s1 in
1375     aux result accu1 accu2 left in
1376     result
1377     | [] ->
1378     if subtype accu2 result
1379     then result
1380     else cup result accu2
1381     in
1382     aux result t any left
1383    
1384     let apply (_,arr) t =
1385     List.fold_left (apply_simple t) empty arr
1386    
1387 abate 19 let need_arg (dom, arr) =
1388     List.exists (function [_] -> false | _ -> true) arr
1389    
1390     let apply_noarg (_,arr) =
1391     List.fold_left
1392     (fun accu ->
1393     function
1394     | [(t,s)] -> cup accu s
1395     | _ -> assert false
1396     )
1397     empty arr
1398    
1399 abate 11 let any = { empty with arrow = any.arrow }
1400 abate 19 let is_empty (_,arr) = arr = []
1401 abate 11 end
1402    
1403    
1404 abate 16 module Int = struct
1405 abate 45 let has_int d i = Intervals.contains i d.ints
1406    
1407 abate 16 let get d = d.ints
1408     let put i = { empty with ints = i }
1409     let is_int d = is_empty { d with ints = Intervals.empty }
1410     let any = { empty with ints = Intervals.any }
1411     end
1412 abate 11
1413 abate 17 module Atom = struct
1414     let has_atom d a = Atoms.contains a d.atoms
1415     end
1416    
1417 abate 45 module Char = struct
1418     let has_char d c = Chars.contains c d.chars
1419 abate 58 let any = { empty with chars = Chars.any }
1420 abate 45 end
1421    
1422 abate 186 let print_stat ppf =
1423 abate 188 (* Format.fprintf ppf "nb_rec = %i@." !nb_rec;
1424 abate 186 Format.fprintf ppf "nb_norec = %i@." !nb_norec;
1425 abate 188 *)
1426 abate 186 ()
1427    
1428 abate 1 (*
1429     let rec print_normal_record ppf = function
1430     | Success -> Format.fprintf ppf "Yes"
1431     | Fail -> Format.fprintf ppf "No"
1432     | FirstLabel (l,present,absent) ->
1433     Format.fprintf ppf "%s?@[<v>@\n" (label_name l);
1434     List.iter
1435     (fun (t,n) ->
1436     Format.fprintf ppf "(%a)=>@[%a@]@\n"
1437     Print.print_descr t
1438     print_normal_record n
1439     ) present;
1440     if absent <> Fail then
1441     Format.fprintf ppf "(absent)=>@[%a@]@\n" print_normal_record absent;
1442     Format.fprintf ppf "@]"
1443     *)
1444    
1445    
1446     (*
1447     let pr s = Types.Print.print Format.std_formatter (Syntax.make_type (Syntax.parse s));;
1448    
1449     let pr' s = Types.Print.print Format.std_formatter
1450     (Types.normalize (Syntax.make_type (Syntax.parse s)));;
1451    
1452     BUG:
1453     pr "'a | 'b where 'a = ('a , 'a) and 'b= ('b , 'b)";;
1454     *)
1455    
1456    
1457     (*
1458     let nr s =
1459     let t = Types.descr (Syntax.make_type (Syntax.parse s)) in
1460     let n = Types.normal_record' t.Types.record in
1461     Types.print_normal_record Format.std_formatter n;;
1462     *)

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