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

Contents of /types/types.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 43 - (show annotations)
Tue Jul 10 17:00:25 2007 UTC (5 years, 10 months ago) by abate
File size: 22559 byte(s)
[r2002-10-26 01:35:24 by cvscast] Empty log message

Original author: cvscast
Date: 2002-10-26 01:35:24+00:00
1 open Recursive
2 open Printf
3
4
5
6 type label = int
7 type atom = int
8
9 type const = Integer of Big_int.big_int | Atom of atom | Char of Chars.Unichar.t
10
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 chars : Chars.t;
19 }
20
21 let empty = {
22 times = Boolean.empty;
23 arrow = Boolean.empty;
24 record= Boolean.empty;
25 ints = Intervals.empty;
26 atoms = Atoms.empty;
27 chars = Chars.empty;
28 }
29
30 let any = {
31 times = Boolean.full;
32 arrow = Boolean.full;
33 record= Boolean.full;
34 ints = Intervals.any;
35 atoms = Atoms.any;
36 chars = Chars.any;
37 }
38
39 let interval i j = { empty with ints = Intervals.atom i j }
40 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 let atom a = { empty with atoms = a }
44 let char c = { empty with chars = c }
45 let constant = function
46 | Integer i -> interval i i
47 | Atom a -> atom (Atoms.atom a)
48 | Char c -> char (Chars.atom c)
49
50
51 let any_record = { empty with record = any.record }
52
53 let cup x y =
54 if x == y then x else {
55 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 chars = Chars.cup x.chars y.chars;
61 }
62
63 let cap x y =
64 if x == y then x else {
65 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 chars = Chars.cap x.chars y.chars;
71 }
72
73 let diff x y =
74 if x == y then empty else {
75 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 chars = Chars.diff x.chars y.chars;
81 }
82
83 let neg x = diff any x
84
85 let equal e a b =
86 if not (Intervals.equal a.ints b.ints) then raise NotEqual;
87 if a.atoms <> b.atoms then raise NotEqual;
88 if a.chars <> b.chars then raise NotEqual;
89 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 chars = a.chars;
102 }
103
104 let hash h a =
105 (Hashtbl.hash { map h a with ints = Intervals.empty })
106 + (Intervals.hash a.ints)
107
108 let iter f a =
109 ignore (map f a)
110
111 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 else if not (Chars.is_empty d.chars) then false
226 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 let old = !memo in
282 let r = empty_rec d in
283 if not r then memo := old;
284 (* cache_false := Assumptions.empty; *)
285 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 | Int of Big_int.big_int
303 | Atom of atom
304 | Char of Chars.Unichar.t
305 | 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 try Char (Chars.sample d.chars) with Not_found ->
318 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 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 and sample_rec_arrow_aux (left,right) =
363 if (check_empty_arrow_line left right) then raise Not_found
364 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
376 end
377
378
379 module Product =
380 struct
381 type t = (descr * descr) list
382
383 let other d = { d with times = empty.times }
384 let is_product d = is_empty (other d)
385
386 let need_second = function _::_::_ -> true | _ -> false
387
388 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 let is_empty d = d = []
444 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 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
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 let project d l =
490 project_field (get_record d.record) l
491
492 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 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 module MapDescr = Map.Make(struct type t = descr let compare = compare end)
546
547 let memo_normalize = DescrHash.create 17
548
549 let map_sort f l =
550 SortedList.from_list (List.map f l)
551
552 let rec rec_normalize d =
553 try DescrHash.find memo_normalize d
554 with Not_found ->
555 let n = make () in
556 DescrHash.add memo_normalize d n;
557 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 descr (internalize (rec_normalize n))
572
573 module Print =
574 struct
575 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 let named = DescrHash.create 10
583 let register_global name d = DescrHash.add named d name
584
585 let marks = DescrHash.create 63
586 let wh = ref []
587 let count_name = ref 0
588 let name () =
589 incr count_name;
590 "X" ^ (string_of_int !count_name)
591 (* TODO:
592 check that these generated names does not conflict with declared types *)
593
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 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
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 let rec print ppf n = print_descr ppf (descr n)
625 and print_descr ppf d =
626 try
627 let name = DescrHash.find named d in
628 Format.fprintf ppf "%s" name
629 with Not_found ->
630 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 and real_print_descr ppf d =
637 if d = any then Format.fprintf ppf "Any" else
638 print_union ppf
639 (Intervals.print d.ints @
640 Chars.print d.chars @
641 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 )
646 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 Format.fprintf ppf " where@ @[%s = %a" na real_print_descr d;
660 List.iter
661 (fun (na,d) ->
662 Format.fprintf ppf " and@ %s = %a" na real_print_descr d)
663 t;
664 Format.fprintf ppf "@]"
665 );
666 Format.fprintf ppf "@]";
667 count_name := 0;
668 wh := [];
669 DescrHash.clear marks
670
671 let print_descr ppf d =
672 mark_descr d;
673 Format.fprintf ppf "@[%a" print_descr d;
674 end_print ppf
675
676 let print ppf n = print_descr ppf (descr n)
677
678 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 | Sample.Int i -> Format.fprintf ppf "%s" (Big_int.string_of_big_int i)
686 | Sample.Atom a -> Format.fprintf ppf "`%s" (atom_name a)
687 | Sample.Char c -> Chars.Unichar.print ppf c
688 | 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 end
712
713 module Arrow =
714 struct
715 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 if not (empty_rec accu1') then aux accu1 accu2 left;
720 let accu2' = cap_t accu2 t2 in
721 if not (empty_rec accu2') then aux accu1 accu2 left
722 | [] -> 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 type t = descr * (descr * descr) list list
741
742 let get t =
743 List.fold_left
744 (fun ((dom,arr) as accu) (left,right) ->
745 if Sample.check_empty_arrow_line left right
746 then accu
747 else (
748 let left =
749 List.map
750 (fun (t,s) -> (descr t, descr s)) left in
751 let d = List.fold_left (fun d (t,_) -> cup d t) empty left in
752 (cap dom d, left :: arr)
753 )
754 )
755 (any, [])
756 t.arrow
757
758 let domain (dom,_) = dom
759
760 let apply_simple t result left =
761 let rec aux result accu1 accu2 = function
762 | (t1,s1)::left ->
763 let result =
764 let accu1 = diff accu1 t1 in
765 if non_empty accu1 then aux result accu1 accu2 left
766 else result in
767 let result =
768 let accu2 = cap accu2 s1 in
769 aux result accu1 accu2 left in
770 result
771 | [] ->
772 if subtype accu2 result
773 then result
774 else cup result accu2
775 in
776 aux result t any left
777
778 let apply (_,arr) t =
779 List.fold_left (apply_simple t) empty arr
780
781 let need_arg (dom, arr) =
782 List.exists (function [_] -> false | _ -> true) arr
783
784 let apply_noarg (_,arr) =
785 List.fold_left
786 (fun accu ->
787 function
788 | [(t,s)] -> cup accu s
789 | _ -> assert false
790 )
791 empty arr
792
793 let any = { empty with arrow = any.arrow }
794 let is_empty (_,arr) = arr = []
795 end
796
797
798 module Int = struct
799 let get d = d.ints
800 let put i = { empty with ints = i }
801 let is_int d = is_empty { d with ints = Intervals.empty }
802 let any = { empty with ints = Intervals.any }
803 end
804
805 module Atom = struct
806 let has_atom d a = Atoms.contains a d.atoms
807 end
808
809 (*
810 let rec print_normal_record ppf = function
811 | Success -> Format.fprintf ppf "Yes"
812 | Fail -> Format.fprintf ppf "No"
813 | FirstLabel (l,present,absent) ->
814 Format.fprintf ppf "%s?@[<v>@\n" (label_name l);
815 List.iter
816 (fun (t,n) ->
817 Format.fprintf ppf "(%a)=>@[%a@]@\n"
818 Print.print_descr t
819 print_normal_record n
820 ) present;
821 if absent <> Fail then
822 Format.fprintf ppf "(absent)=>@[%a@]@\n" print_normal_record absent;
823 Format.fprintf ppf "@]"
824 *)
825
826
827 (*
828 let pr s = Types.Print.print Format.std_formatter (Syntax.make_type (Syntax.parse s));;
829
830 let pr' s = Types.Print.print Format.std_formatter
831 (Types.normalize (Syntax.make_type (Syntax.parse s)));;
832
833 BUG:
834 pr "'a | 'b where 'a = ('a , 'a) and 'b= ('b , 'b)";;
835 *)
836
837
838 (*
839 let nr s =
840 let t = Types.descr (Syntax.make_type (Syntax.parse s)) in
841 let n = Types.normal_record' t.Types.record in
842 Types.print_normal_record Format.std_formatter n;;
843 *)

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