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

Contents of /types/types.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 74 - (hide annotations)
Tue Jul 10 17:03:46 2007 UTC (5 years, 11 months ago) by abate
File size: 24662 byte(s)
[r2002-11-01 22:06:20 by cvscast] Empty log message

Original author: cvscast
Date: 2002-11-01 22:06:20+00:00
1 abate 1 open Recursive
2     open Printf
3    
4    
5    
6     type label = int
7     type atom = int
8    
9 abate 71 let counter_label = ref 0
10     let label_table = Hashtbl.create 63
11     let label_names = Hashtbl.create 63
12    
13     let label s =
14     try Hashtbl.find label_table s
15     with Not_found ->
16     incr counter_label;
17     Hashtbl.add label_table s !counter_label;
18     Hashtbl.add label_names !counter_label s;
19     !counter_label
20    
21     let label_name l =
22     Hashtbl.find label_names l
23    
24     let mk_atom = label
25    
26     let atom_name = label_name
27    
28 abate 15 type const = Integer of Big_int.big_int | Atom of atom | Char of Chars.Unichar.t
29 abate 1
30     module I = struct
31     type 'a t = {
32     ints : Intervals.t;
33     atoms : atom Atoms.t;
34     times : ('a * 'a) Boolean.t;
35     arrow : ('a * 'a) Boolean.t;
36     record: (label * bool * 'a) Boolean.t;
37 abate 13 chars : Chars.t;
38 abate 1 }
39 abate 15
40 abate 1 let empty = {
41     times = Boolean.empty;
42     arrow = Boolean.empty;
43     record= Boolean.empty;
44     ints = Intervals.empty;
45     atoms = Atoms.empty;
46 abate 13 chars = Chars.empty;
47 abate 1 }
48 abate 15
49 abate 1 let any = {
50     times = Boolean.full;
51     arrow = Boolean.full;
52     record= Boolean.full;
53 abate 15 ints = Intervals.any;
54 abate 18 atoms = Atoms.any;
55     chars = Chars.any;
56 abate 1 }
57    
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     let arrow x y = { empty with arrow = Boolean.atom (x,y) }
61     let record label opt t = { empty with record = Boolean.atom (label,opt,t) }
62 abate 18 let atom a = { empty with atoms = a }
63     let char c = { empty with chars = c }
64 abate 1 let constant = function
65 abate 52 | Integer i -> interval (Intervals.atom i)
66 abate 18 | Atom a -> atom (Atoms.atom a)
67     | Char c -> char (Chars.atom c)
68 abate 1
69    
70     let any_record = { empty with record = any.record }
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     arrow = Boolean.cup x.arrow y.arrow;
76     record= Boolean.cup x.record y.record;
77     ints = Intervals.cup x.ints y.ints;
78     atoms = Atoms.cup x.atoms y.atoms;
79 abate 13 chars = Chars.cup x.chars y.chars;
80 abate 8 }
81    
82     let cap x y =
83 abate 69 if x = y then x else {
84 abate 8 times = Boolean.cap x.times y.times;
85     record= Boolean.cap x.record y.record;
86     arrow = Boolean.cap x.arrow y.arrow;
87     ints = Intervals.cap x.ints y.ints;
88     atoms = Atoms.cap x.atoms y.atoms;
89 abate 13 chars = Chars.cap x.chars y.chars;
90 abate 8 }
91    
92     let diff x y =
93 abate 69 if x = y then empty else {
94 abate 8 times = Boolean.diff x.times y.times;
95     arrow = Boolean.diff x.arrow y.arrow;
96     record= Boolean.diff x.record y.record;
97     ints = Intervals.diff x.ints y.ints;
98     atoms = Atoms.diff x.atoms y.atoms;
99 abate 13 chars = Chars.diff x.chars y.chars;
100 abate 8 }
101    
102 abate 1 let neg x = diff any x
103    
104     let equal e a b =
105     if a.atoms <> b.atoms then raise NotEqual;
106 abate 13 if a.chars <> b.chars then raise NotEqual;
107 abate 69 if a.ints <> b.ints then raise NotEqual;
108 abate 1 Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.times b.times;
109     Boolean.equal (fun (x1,x2) (y1,y2) -> e x1 y1; e x2 y2) a.arrow b.arrow;
110     Boolean.equal (fun (l1,o1,x1) (l2,o2,x2) ->
111     if (l1 <> l2) || (o1 <> o2) then raise NotEqual;
112     e x1 x2) a.record b.record
113    
114     let map f a =
115     { times = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.times;
116     arrow = Boolean.map (fun (x1,x2) -> (f x1, f x2)) a.arrow;
117     record= Boolean.map (fun (l,o,x) -> (l,o, f x)) a.record;
118     ints = a.ints;
119     atoms = a.atoms;
120 abate 13 chars = a.chars;
121 abate 1 }
122    
123     let hash h a =
124 abate 69 Hashtbl.hash (map h a)
125     (*
126 abate 60 (Hashtbl.hash { (map h a) with ints = Intervals.empty })
127 abate 15 + (Intervals.hash a.ints)
128 abate 69 *)
129 abate 1
130     let iter f a =
131     ignore (map f a)
132 abate 16
133 abate 1 let deep = 4
134     end
135    
136    
137 abate 67 module Algebra = Recursive_noshare.Make(I)
138 abate 1 include I
139     include Algebra
140 abate 71 module DescrHash =
141     Hashtbl.Make(
142     struct
143     type t = descr
144     let hash = hash_descr
145     let equal = equal_descr
146     end
147     )
148 abate 1
149 abate 71 module DescrMap = Map.Make(struct type t = descr let compare = compare end)
150    
151 abate 1 let check d =
152     Boolean.check d.times;
153     Boolean.check d.arrow;
154     Boolean.check d.record;
155     ()
156    
157     (*
158     let define n d = check d; define n d
159     *)
160    
161     let cons d =
162     let n = make () in
163     define n d;
164     internalize n
165    
166    
167 abate 71 module Print =
168     struct
169     let print_atom ppf a = Format.fprintf ppf "`%s" (atom_name a)
170    
171     let print_const ppf = function
172     | Integer i -> Format.fprintf ppf "%s" (Big_int.string_of_big_int i)
173     | Atom a -> print_atom ppf a
174     | Char c -> Chars.Unichar.print ppf c
175    
176     let named = DescrHash.create 10
177     let register_global name d = DescrHash.add named d name
178    
179     let marks = DescrHash.create 63
180     let wh = ref []
181     let count_name = ref 0
182     let name () =
183     incr count_name;
184     "X" ^ (string_of_int !count_name)
185     (* TODO:
186     check that these generated names does not conflict with declared types *)
187    
188     let bool_iter f b =
189     List.iter (fun (p,n) -> List.iter f p; List.iter f n) b
190    
191     let trivial b = b = Boolean.empty || b = Boolean.full
192    
193     let worth_abbrev d =
194     not (trivial d.times && trivial d.arrow && trivial d.record)
195    
196     let rec mark n = mark_descr (descr n)
197     and mark_descr d =
198     if not (DescrHash.mem named d) then
199     try
200     let r = DescrHash.find marks d in
201     if (!r = None) && (worth_abbrev d) then
202     let na = name () in
203     r := Some na;
204     wh := (na,d) :: !wh
205     with Not_found ->
206     DescrHash.add marks d (ref None);
207     bool_iter (fun (n1,n2) -> mark n1; mark n2) d.times;
208     bool_iter (fun (n1,n2) -> mark n1; mark n2) d.arrow;
209     bool_iter (fun (l,o,n) -> mark n) d.record
210    
211    
212     let rec print_union ppf = function
213     | [] -> Format.fprintf ppf "Empty"
214     | [h] -> h ppf
215     | h::t -> Format.fprintf ppf "@[%t |@ %a@]" h print_union t
216    
217    
218     let rec print ppf n = print_descr ppf (descr n)
219     and print_descr ppf d =
220     try
221     let name = DescrHash.find named d in
222     Format.fprintf ppf "%s" name
223     with Not_found ->
224     try
225     match !(DescrHash.find marks d) with
226     | Some n -> Format.fprintf ppf "%s" n
227     | None -> real_print_descr ppf d
228     with
229     Not_found -> Format.fprintf ppf "XXX"
230     and real_print_descr ppf d =
231     if d = any then Format.fprintf ppf "Any" else
232     print_union ppf
233     (Intervals.print d.ints @
234     Chars.print d.chars @
235     Atoms.print "Atom" print_atom d.atoms @
236     Boolean.print "Pair" print_times d.times @
237     Boolean.print "Arrow" print_arrow d.arrow @
238     Boolean.print "Record" print_record d.record
239     )
240     and print_times ppf (t1,t2) =
241     Format.fprintf ppf "@[(%a,%a)@]" print t1 print t2
242     and print_arrow ppf (t1,t2) =
243     Format.fprintf ppf "@[(%a -> %a)@]" print t1 print t2
244     and print_record ppf (l,o,t) =
245     Format.fprintf ppf "@[{ %s =%s %a }@]"
246     (label_name l) (if o then "?" else "") print t
247    
248    
249     let end_print ppf =
250     (match List.rev !wh with
251     | [] -> ()
252     | (na,d)::t ->
253     Format.fprintf ppf " where@ @[%s = %a" na real_print_descr d;
254     List.iter
255     (fun (na,d) ->
256     Format.fprintf ppf " and@ %s = %a" na real_print_descr d)
257     t;
258     Format.fprintf ppf "@]"
259     );
260     Format.fprintf ppf "@]";
261     count_name := 0;
262     wh := [];
263     DescrHash.clear marks
264    
265     let print_descr ppf d =
266     mark_descr d;
267     Format.fprintf ppf "@[%a" print_descr d;
268     end_print ppf
269    
270     let print ppf n = print_descr ppf (descr n)
271    
272     end
273    
274    
275    
276 abate 1 module Positive =
277     struct
278     type rhs = [ `Type of descr | `Cup of v list | `Times of v * v ]
279     and v = { mutable def : rhs; mutable node : node option }
280    
281    
282     let rec make_descr seen v =
283     if List.memq v seen then empty
284     else
285     let seen = v :: seen in
286     match v.def with
287     | `Type d -> d
288     | `Cup vl ->
289     List.fold_left (fun acc v -> cup acc (make_descr seen v)) empty vl
290     | `Times (v1,v2) -> times (make_node v1) (make_node v2)
291    
292     and make_node v =
293     match v.node with
294     | Some n -> n
295     | None ->
296     let n = make () in
297     v.node <- Some n;
298     let d = make_descr [] v in
299     define n d;
300     n
301    
302     let forward () = { def = `Cup []; node = None }
303     let def v d = v.def <- d
304     let cons d = let v = forward () in def v d; v
305     let ty d = cons (`Type d)
306     let cup vl = cons (`Cup vl)
307     let times d1 d2 = cons (`Times (d1,d2))
308     let define v1 v2 = def v1 (`Cup [v2])
309    
310     let solve v = internalize (make_node v)
311     end
312    
313    
314     let get_record r =
315     let add = SortedMap.add (fun (o1,t1) (o2,t2) -> (o1&&o2, cap t1 t2)) in
316     let line (p,n) =
317     let accu = List.fold_left
318     (fun accu (l,o,t) -> add l (o,descr t) accu) [] p in
319     List.fold_left
320     (fun accu (l,o,t) -> add l (not o,neg (descr t)) accu) accu n in
321     List.map line r
322    
323    
324    
325     (* Subtyping algorithm *)
326    
327     let diff_t d t = diff d (descr t)
328     let cap_t d t = cap d (descr t)
329     let cap_product l =
330     List.fold_left
331     (fun (d1,d2) (t1,t2) -> (cap_t d1 t1, cap_t d2 t2))
332     (any,any)
333     l
334    
335    
336     module Assumptions = Set.Make(struct type t = descr let compare = compare end)
337    
338     let memo = ref Assumptions.empty
339     let cache_false = ref Assumptions.empty
340    
341     exception NotEmpty
342    
343     let rec empty_rec d =
344     if Assumptions.mem d !cache_false then false
345     else if Assumptions.mem d !memo then true
346     else if not (Intervals.is_empty d.ints) then false
347     else if not (Atoms.is_empty d.atoms) then false
348 abate 13 else if not (Chars.is_empty d.chars) then false
349 abate 1 else (
350     let backup = !memo in
351     memo := Assumptions.add d backup;
352     if
353     (empty_rec_times d.times) &&
354     (empty_rec_arrow d.arrow) &&
355     (empty_rec_record d.record)
356     then true
357     else (
358     memo := backup;
359     cache_false := Assumptions.add d !cache_false;
360     false
361     )
362     )
363    
364     and empty_rec_times c =
365     List.for_all empty_rec_times_aux c
366    
367     and empty_rec_times_aux (left,right) =
368     let rec aux accu1 accu2 = function
369     | (t1,t2)::right ->
370     let accu1' = diff_t accu1 t1 in
371     if not (empty_rec accu1') then aux accu1' accu2 right;
372     let accu2' = diff_t accu2 t2 in
373     if not (empty_rec accu2') then aux accu1 accu2' right
374     | [] -> raise NotEmpty
375     in
376     let (accu1,accu2) = cap_product left in
377     (empty_rec accu1) || (empty_rec accu2) ||
378     (try aux accu1 accu2 right; true with NotEmpty -> false)
379    
380     and empty_rec_arrow c =
381     List.for_all empty_rec_arrow_aux c
382    
383     and empty_rec_arrow_aux (left,right) =
384     let single_right (s1,s2) =
385     let rec aux accu1 accu2 = function
386     | (t1,t2)::left ->
387     let accu1' = diff_t accu1 t1 in
388     if not (empty_rec accu1') then aux accu1 accu2 left;
389     let accu2' = cap_t accu2 t2 in
390     if not (empty_rec accu2') then aux accu1 accu2 left
391     | [] -> raise NotEmpty
392     in
393     let accu1 = descr s1 in
394     (empty_rec accu1) ||
395     (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)
396     in
397     List.exists single_right right
398    
399     and empty_rec_record c =
400     let aux = List.exists (fun (_,(opt,t)) -> (not opt) && (empty_rec t)) in
401     List.for_all aux (get_record c)
402    
403     let is_empty d =
404 abate 20 let old = !memo in
405 abate 1 let r = empty_rec d in
406 abate 20 if not r then memo := old;
407 abate 22 (* cache_false := Assumptions.empty; *)
408 abate 1 r
409    
410     let non_empty d =
411     not (is_empty d)
412    
413     let subtype d1 d2 =
414     is_empty (diff d1 d2)
415    
416     (* Sample value *)
417     module Sample =
418     struct
419    
420     let rec find f = function
421     | [] -> raise Not_found
422     | x::r -> try f x with Not_found -> find f r
423    
424     type t =
425 abate 15 | Int of Big_int.big_int
426 abate 1 | Atom of atom
427 abate 13 | Char of Chars.Unichar.t
428 abate 1 | Pair of t * t
429     | Record of (label * t) list
430     | Fun of (node * node) list
431    
432     let rec gen_atom i l =
433     if SortedList.mem l i then gen_atom (succ i) l else i
434    
435     let rec sample_rec memo d =
436     if (Assumptions.mem d memo) || (is_empty d) then raise Not_found
437     else
438     try Int (Intervals.sample d.ints) with Not_found ->
439     try Atom (Atoms.sample (gen_atom 0) d.atoms) with Not_found ->
440 abate 13 try Char (Chars.sample d.chars) with Not_found ->
441 abate 1 try sample_rec_arrow d.arrow with Not_found ->
442    
443     let memo = Assumptions.add d memo in
444     try sample_rec_times memo d.times with Not_found ->
445     try sample_rec_record memo d.record with Not_found ->
446     raise Not_found
447    
448    
449     and sample_rec_times memo c =
450     find (sample_rec_times_aux memo) c
451    
452     and sample_rec_times_aux memo (left,right) =
453     let rec aux accu1 accu2 = function
454     | (t1,t2)::right ->
455     let accu1' = diff_t accu1 t1 in
456     if non_empty accu1' then aux accu1' accu2 right else
457     let accu2' = diff_t accu2 t2 in
458     if non_empty accu2' then aux accu1 accu2' right else
459     raise Not_found
460     | [] -> Pair (sample_rec memo accu1, sample_rec memo accu2)
461     in
462     let (accu1,accu2) = cap_product left in
463     if (is_empty accu1) || (is_empty accu2) then raise Not_found;
464     aux accu1 accu2 right
465    
466     and sample_rec_arrow c =
467     find sample_rec_arrow_aux c
468    
469 abate 10 and check_empty_simple_arrow_line left (s1,s2) =
470     let rec aux accu1 accu2 = function
471     | (t1,t2)::left ->
472     let accu1' = diff_t accu1 t1 in
473     if non_empty accu1' then aux accu1 accu2 left;
474     let accu2' = cap_t accu2 t2 in
475     if non_empty accu2' then aux accu1 accu2 left
476     | [] -> raise NotEmpty
477     in
478     let accu1 = descr s1 in
479     (is_empty accu1) ||
480     (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)
481    
482     and check_empty_arrow_line left right =
483     List.exists (check_empty_simple_arrow_line left) right
484    
485 abate 1 and sample_rec_arrow_aux (left,right) =
486 abate 10 if (check_empty_arrow_line left right) then raise Not_found
487 abate 1 else Fun left
488    
489    
490     and sample_rec_record memo c =
491     Record (find (sample_rec_record_aux memo) (get_record c))
492    
493     and sample_rec_record_aux memo fields =
494     let aux acc (l,(o,t)) = if o then acc else (l, sample_rec memo t) :: acc in
495     List.fold_left aux [] fields
496    
497     let get x = sample_rec Assumptions.empty x
498 abate 10
499 abate 71 let rec print_sep f sep ppf = function
500     | [] -> ()
501     | [x] -> f ppf x
502     | x::rem -> f ppf x; Format.fprintf ppf "%s" sep; print_sep f sep ppf rem
503    
504    
505     let rec print ppf = function
506     | Int i -> Format.fprintf ppf "%s" (Big_int.string_of_big_int i)
507     | Atom a -> Format.fprintf ppf "`%s" (atom_name a)
508     | Char c -> Chars.Unichar.print ppf c
509     | Pair (x1,x2) -> Format.fprintf ppf "(%a,%a)" print x1 print x2
510     | Record r ->
511     Format.fprintf ppf "{ %a }"
512     (print_sep
513     (fun ppf (l,x) ->
514     Format.fprintf ppf "%s = %a"
515     (label_name l)
516     print x
517     )
518     " ; "
519     ) r
520     | Fun iface ->
521     Format.fprintf ppf "(fun ( %a ) x -> ...)"
522     (print_sep
523     (fun ppf (t1,t2) ->
524     Format.fprintf ppf "%a -> %a; "
525     Print.print t1 Print.print t2
526     )
527     " ; "
528     ) iface
529 abate 1 end
530    
531    
532     module Product =
533     struct
534     type t = (descr * descr) list
535    
536 abate 17 let other d = { d with times = empty.times }
537     let is_product d = is_empty (other d)
538    
539 abate 19 let need_second = function _::_::_ -> true | _ -> false
540    
541 abate 71 let normal_aux d =
542     let res = ref [] in
543    
544     let add (t1,t2) =
545     let rec loop t1 t2 = function
546     | [] -> res := (ref (t1,t2)) :: !res
547     | ({contents = (d1,d2)} as r)::l ->
548     (*OPT*)
549     if d1 = t1 then r := (d1,cup d2 t2) else
550    
551     let i = cap t1 d1 in
552     if is_empty i then loop t1 t2 l
553     else (
554     r := (i, cup t2 d2);
555     let k = diff d1 t1 in
556     if non_empty k then res := (ref (k,d2)) :: !res;
557    
558     let j = diff t1 d1 in
559     if non_empty j then loop j t2 l
560     )
561     in
562     loop t1 t2 !res
563     in
564     List.iter add d;
565     List.map (!) !res
566    
567     (*
568     This version explodes when dealing with
569     Any - [ t1? t2? t3? ... tn? ]
570     ==> need partitioning
571     *)
572     let get_aux d =
573 abate 1 let line accu (left,right) =
574 abate 71 let debug = List.length right = 28 in
575 abate 1 let rec aux accu d1 d2 = function
576     | (t1,t2)::right ->
577     let accu =
578     let d1 = diff_t d1 t1 in
579     if is_empty d1 then accu else aux accu d1 d2 right in
580     let accu =
581     let d2 = diff_t d2 t2 in
582     if is_empty d2 then accu else aux accu d1 d2 right in
583     accu
584 abate 71 | [] -> (d1,d2) :: accu
585 abate 1 in
586     let (d1,d2) = cap_product left in
587     if (is_empty d1) || (is_empty d2) then accu else aux accu d1 d2 right
588     in
589 abate 71 List.fold_left line [] d
590 abate 1
591 abate 74 (* Partitioning:
592 abate 71
593 abate 74 (t,s) - ((t1,s1) | (t2,s2) | ... | (tn,sn))
594     =
595     (t & t1, s - s1) | ... | (t & tn, s - sn) | (t - (t1|...|tn), s)
596    
597     *)
598    
599 abate 71 let get_aux d =
600     let accu = ref [] in
601     let line (left,right) =
602     let (d1,d2) = cap_product left in
603     if (non_empty d1) && (non_empty d2) then
604     let right = List.map (fun (t1,t2) -> descr t1, descr t2) right in
605     let right = normal_aux right in
606     let resid1 = ref d1 in
607     let () =
608     List.iter
609     (fun (t1,t2) ->
610     let t1 = cap d1 t1 in
611     if (non_empty t1) then
612     let () = resid1 := diff !resid1 t1 in
613     let t2 = diff d2 t2 in
614     if (non_empty t2) then accu := (t1,t2) :: !accu
615     ) right in
616     if non_empty !resid1 then accu := (!resid1, d2) :: !accu
617     in
618     List.iter line d;
619     !accu
620    
621     let get d = get_aux d.times
622    
623 abate 1 let pi1 = List.fold_left (fun acc (t1,_) -> cup acc t1) empty
624     let pi2 = List.fold_left (fun acc (_,t2) -> cup acc t2) empty
625    
626     let restrict_1 rects pi1 =
627     let aux accu (t1,t2) =
628     let t1 = cap t1 pi1 in if is_empty t1 then accu else (t1,t2)::accu in
629     List.fold_left aux [] rects
630    
631     type normal = t
632    
633 abate 71 module Memo = Map.Make(struct
634     type t = (node * node) Boolean.t
635     let compare = compare end)
636    
637 abate 1
638    
639 abate 71 let memo = ref Memo.empty
640     let normal d =
641     let d = d.times in
642     try Memo.find d !memo
643     with
644     Not_found ->
645     let gd = get_aux d in
646     let n = normal_aux gd in
647     memo := Memo.add d n !memo;
648     n
649    
650 abate 1 let any = { empty with times = any.times }
651 abate 19 let is_empty d = d = []
652 abate 1 end
653    
654    
655     module Record =
656     struct
657     type t = (label, (bool * descr)) SortedMap.t list
658    
659     let get d =
660     let line r = List.for_all (fun (l,(o,d)) -> o || non_empty d) r in
661     List.filter line (get_record d.record)
662    
663    
664     let restrict_label_present t l =
665 abate 29 let restr = function
666     | (true, d) -> if non_empty d then (false,d) else raise Exit
667     | x -> x in
668     let aux accu r =
669     try SortedMap.change l restr (false,any) r :: accu
670     with Exit -> accu in
671     List.fold_left aux [] t
672 abate 1
673     let restrict_label_absent t l =
674     let restr = function (true, _) -> (true,empty) | _ -> raise Exit in
675     let aux accu r =
676     try SortedMap.change l restr (true,empty) r :: accu
677     with Exit -> accu in
678     List.fold_left aux [] t
679    
680     let restrict_field t l d =
681     let restr (_,d1) =
682     let d1 = cap d d1 in
683     if is_empty d1 then raise Exit else (false,d1) in
684     let aux accu r =
685     try SortedMap.change l restr (false,d) r :: accu
686     with Exit -> accu in
687     List.fold_left aux [] t
688    
689     let project_field t l =
690     let aux accu x =
691     match List.assoc l x with
692     | (false,t) -> cup accu t
693     | _ -> raise Not_found
694     in
695     List.fold_left aux empty t
696    
697 abate 29 let project d l =
698     project_field (get_record d.record) l
699    
700 abate 1 type normal =
701     [ `Success
702     | `Fail
703     | `Label of label * (descr * normal) list * normal ]
704    
705     let rec merge_record n r =
706     match (n, r) with
707     | (`Success, _) | (_, []) -> `Success
708     | (`Fail, r) ->
709     let aux (l,(o,t)) n = `Label (l, [t,n], if o then n else `Fail) in
710     List.fold_right aux r `Success
711     | (`Label (l1,present,absent), (l2,(o,t2))::r') ->
712     if (l1 < l2) then
713     let pr = List.map (fun (t,x) -> (t, merge_record x r)) present in
714     `Label (l1,pr,merge_record absent r)
715     else if (l2 < l1) then
716     let n' = merge_record n r' in
717     `Label (l2, [t2, n'], if o then n' else n)
718     else
719     let res = ref [] in
720     let aux a (t,x) =
721     (let t = diff t t2 in
722     if non_empty t then res := (t,x) :: !res);
723     (let t = cap t t2 in
724     if non_empty t then res := (t, merge_record x r') :: !res);
725     diff a t
726     in
727     let t2 = List.fold_left aux t2 present in
728     let () =
729     if non_empty t2 then
730     res := (t2, merge_record `Fail r') :: !res in
731     let abs = if o then merge_record absent r' else absent in
732     `Label (l1, !res, abs)
733    
734    
735     let normal d =
736     List.fold_left merge_record `Fail (get d)
737    
738    
739     let any = { empty with record = any.record }
740     let is_empty d = d = []
741     end
742    
743    
744 abate 29
745 abate 71 let memo_normalize = ref DescrMap.empty
746 abate 1
747     let map_sort f l =
748     SortedList.from_list (List.map f l)
749    
750     let rec rec_normalize d =
751 abate 71 try DescrMap.find d !memo_normalize
752 abate 1 with Not_found ->
753     let n = make () in
754 abate 71 memo_normalize := DescrMap.add d n !memo_normalize;
755 abate 1 let times =
756     map_sort
757     (fun (d1,d2) -> [(rec_normalize d1, rec_normalize d2)],[])
758     (Product.normal d)
759     in
760     let record =
761     map_sort
762     (fun f -> map_sort (fun (l,(o,d)) -> (l,o,rec_normalize d)) f, [])
763     (Record.get d)
764     in
765     define n { d with times = times; record = record };
766     n
767    
768     let normalize n =
769 abate 29 descr (internalize (rec_normalize n))
770 abate 6
771 abate 11 module Arrow =
772     struct
773 abate 19 let check_simple left s1 s2 =
774     let rec aux accu1 accu2 = function
775     | (t1,t2)::left ->
776     let accu1' = diff_t accu1 t1 in
777 abate 45 if non_empty accu1' then aux accu1 accu2 left;
778 abate 19 let accu2' = cap_t accu2 t2 in
779 abate 45 if non_empty accu2' then aux accu1 accu2 left
780 abate 19 | [] -> raise NotEmpty
781     in
782     let accu1 = descr s1 in
783     (is_empty accu1) ||
784     (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)
785    
786     let check_strenghten t s =
787     let left = match t.arrow with [ (p,[]) ] -> p | _ -> assert false in
788     let rec aux = function
789     | [] -> raise Not_found
790     | (p,n) :: rem ->
791     if (List.for_all (fun (a,b) -> check_simple left a b) p) &&
792     (List.for_all (fun (a,b) -> not (check_simple left a b)) n) then
793     { empty with arrow = [ (SortedList.cup left p, n) ] }
794     else aux rem
795     in
796     aux s.arrow
797    
798 abate 45 let check_simple_iface left s1 s2 =
799     let rec aux accu1 accu2 = function
800     | (t1,t2)::left ->
801     let accu1' = diff accu1 t1 in
802     if non_empty accu1' then aux accu1 accu2 left;
803     let accu2' = cap accu2 t2 in
804     if non_empty accu2' then aux accu1 accu2 left
805     | [] -> raise NotEmpty
806     in
807     let accu1 = descr s1 in
808     (is_empty accu1) ||
809     (try aux accu1 (diff any (descr s2)) left; true with NotEmpty -> false)
810    
811     let check_iface iface s =
812     let rec aux = function
813     | [] -> false
814     | (p,n) :: rem ->
815     ((List.for_all (fun (a,b) -> check_simple_iface iface a b) p) &&
816     (List.for_all (fun (a,b) -> not (check_simple_iface iface a b)) n))
817     || (aux rem)
818     in
819     aux s.arrow
820    
821 abate 11 type t = descr * (descr * descr) list list
822    
823     let get t =
824     List.fold_left
825     (fun ((dom,arr) as accu) (left,right) ->
826     if Sample.check_empty_arrow_line left right
827     then accu
828     else (
829     let left =
830     List.map
831     (fun (t,s) -> (descr t, descr s)) left in
832     let d = List.fold_left (fun d (t,_) -> cup d t) empty left in
833     (cap dom d, left :: arr)
834     )
835     )
836     (any, [])
837     t.arrow
838    
839     let domain (dom,_) = dom
840    
841     let apply_simple t result left =
842     let rec aux result accu1 accu2 = function
843     | (t1,s1)::left ->
844     let result =
845     let accu1 = diff accu1 t1 in
846     if non_empty accu1 then aux result accu1 accu2 left
847     else result in
848     let result =
849     let accu2 = cap accu2 s1 in
850     aux result accu1 accu2 left in
851     result
852     | [] ->
853     if subtype accu2 result
854     then result
855     else cup result accu2
856     in
857     aux result t any left
858    
859     let apply (_,arr) t =
860     List.fold_left (apply_simple t) empty arr
861    
862 abate 19 let need_arg (dom, arr) =
863     List.exists (function [_] -> false | _ -> true) arr
864    
865     let apply_noarg (_,arr) =
866     List.fold_left
867     (fun accu ->
868     function
869     | [(t,s)] -> cup accu s
870     | _ -> assert false
871     )
872     empty arr
873    
874 abate 11 let any = { empty with arrow = any.arrow }
875 abate 19 let is_empty (_,arr) = arr = []
876 abate 11 end
877    
878    
879 abate 16 module Int = struct
880 abate 45 let has_int d i = Intervals.contains i d.ints
881    
882 abate 16 let get d = d.ints
883     let put i = { empty with ints = i }
884     let is_int d = is_empty { d with ints = Intervals.empty }
885     let any = { empty with ints = Intervals.any }
886     end
887 abate 11
888 abate 17 module Atom = struct
889     let has_atom d a = Atoms.contains a d.atoms
890     end
891    
892 abate 45 module Char = struct
893     let has_char d c = Chars.contains c d.chars
894 abate 58 let any = { empty with chars = Chars.any }
895 abate 45 end
896    
897 abate 1 (*
898     let rec print_normal_record ppf = function
899     | Success -> Format.fprintf ppf "Yes"
900     | Fail -> Format.fprintf ppf "No"
901     | FirstLabel (l,present,absent) ->
902     Format.fprintf ppf "%s?@[<v>@\n" (label_name l);
903     List.iter
904     (fun (t,n) ->
905     Format.fprintf ppf "(%a)=>@[%a@]@\n"
906     Print.print_descr t
907     print_normal_record n
908     ) present;
909     if absent <> Fail then
910     Format.fprintf ppf "(absent)=>@[%a@]@\n" print_normal_record absent;
911     Format.fprintf ppf "@]"
912     *)
913    
914    
915     (*
916     let pr s = Types.Print.print Format.std_formatter (Syntax.make_type (Syntax.parse s));;
917    
918     let pr' s = Types.Print.print Format.std_formatter
919     (Types.normalize (Syntax.make_type (Syntax.parse s)));;
920    
921     BUG:
922     pr "'a | 'b where 'a = ('a , 'a) and 'b= ('b , 'b)";;
923     *)
924    
925    
926     (*
927     let nr s =
928     let t = Types.descr (Syntax.make_type (Syntax.parse s)) in
929     let n = Types.normal_record' t.Types.record in
930     Types.print_normal_record Format.std_formatter n;;
931     *)

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