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

Contents of /types/types.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 156 - (hide annotations)
Tue Jul 10 17:11:11 2007 UTC (5 years, 10 months ago) by abate
File size: 37628 byte(s)
[r2002-11-25 23:29:46 by cvscast] Empty log message

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

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