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

Contents of /types/types.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 52 - (hide annotations)
Tue Jul 10 17:01:20 2007 UTC (5 years, 10 months ago) by abate
File size: 23402 byte(s)
[r2002-10-26 20:45:22 by cvscast] Empty log message

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

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