|
| 1 | +(** Täisarvude abstraheerimise domeenid. *) |
| 2 | + |
| 3 | +(** Täisarvude domeeni liides. *) |
| 4 | +module type S = |
| 5 | +sig |
| 6 | + include Domain.S |
| 7 | + |
| 8 | + (** Loob konkreetsele täisarvule vastava elemendi. *) |
| 9 | + val of_int: int -> t |
| 10 | + |
| 11 | + (** Loob intervallist juhuarvule vastava elemendi. *) |
| 12 | + val of_interval: int * int -> t |
| 13 | + |
| 14 | + (** Väärtustab binaarse operaatori. *) |
| 15 | + val eval_binary: t -> Ast.binary -> t -> t |
| 16 | + |
| 17 | + (** Välistab konkreetse täisarvu. *) |
| 18 | + val exclude: int -> t -> t |
| 19 | +end |
| 20 | + |
| 21 | +(** Täisarvude hulkade domeen. *) |
| 22 | +module Set = |
| 23 | +struct |
| 24 | + include SetDomain.Make (struct type t = int [@@deriving ord, show] end) |
| 25 | + let of_int i = singleton i |
| 26 | + let of_interval (l, u) = S.of_list (List.init (u - l + 1) (fun i -> l + i)) |
| 27 | + |
| 28 | + (** Rakendab binaarset operaatorit kõikvõimalikele paaridele. *) |
| 29 | + let eval_binary s1 b s2 = |
| 30 | + fold (fun i1 acc -> |
| 31 | + fold (fun i2 acc -> |
| 32 | + add (Eval.Concrete.eval_binary i1 b i2) acc |
| 33 | + ) s2 acc |
| 34 | + ) s1 empty |
| 35 | + |
| 36 | + let exclude i s = remove i s |
| 37 | +end |
| 38 | + |
| 39 | +(** Konstantide domeen. |
| 40 | + "Lame" täisarvude võre, mis võimaldab esitada konkreetseid täisarve, |
| 41 | + kuid mitte-konstandid on täiesti tundmatud. *) |
| 42 | +module Flat = |
| 43 | +struct |
| 44 | + include Domain.Flat (struct type t = int [@@deriving eq, ord, show] end) |
| 45 | + let of_int i = Lift i |
| 46 | + let of_interval ((l, u): int * int): t = |
| 47 | + failwith "TODO" |
| 48 | + |
| 49 | + (** Vihje: Eval.Concrete.eval_binary. *) |
| 50 | + let eval_binary (i1: t) (b: Ast.binary) (i2: t): t = |
| 51 | + failwith "TODO" |
| 52 | + |
| 53 | + let exclude (i: int) (i': t): t = |
| 54 | + failwith "TODO" |
| 55 | +end |
| 56 | + |
| 57 | +(** Intervallide domeen. *) |
| 58 | +module Interval = |
| 59 | +struct |
| 60 | + module Interval = |
| 61 | + struct |
| 62 | + type t = int * int [@@deriving eq, ord] |
| 63 | + |
| 64 | + let pp ppf (l, u) = Format.fprintf ppf "[%d, %d]" l u |
| 65 | + let show = Format.asprintf "%a" pp |
| 66 | + |
| 67 | + let leq ((l1, u1): t) ((l2, u2): t): bool = |
| 68 | + failwith "TODO" |
| 69 | + |
| 70 | + let join ((l1, u1): t) ((l2, u2): t): t = |
| 71 | + failwith "TODO" |
| 72 | + |
| 73 | + let eval_binary ((l1, u1): t) (b: Ast.binary) ((l2, u2): t): t = |
| 74 | + match b with |
| 75 | + |
| 76 | + | Eq | Ne | Lt | Le | Gt | Ge -> (0, 1) (* Võrdluse tulemus on 0 või 1, mis on korrektne, aga mitte täpne. Ettepoole saab implementeerida täpsemad juhud kui vaja. *) |
| 77 | + |
| 78 | + | _ -> failwith "TODO" (* Ei pea implementeerima kõiki operaatoreid, vaid ainult testideks vajalikud. *) |
| 79 | + end |
| 80 | + (* Lisame tehisliku vähima elemendi, |
| 81 | + millega tähistame võimatut täisarvulist väärtust. *) |
| 82 | + include Domain.LiftBot (Interval) |
| 83 | + |
| 84 | + let of_interval (l, u) = Lift (l, u) |
| 85 | + let of_int i = of_interval (i, i) |
| 86 | + |
| 87 | + let eval_binary x1 b x2 = |
| 88 | + match x1, x2 with |
| 89 | + | Bot, _ |
| 90 | + | _, Bot -> Bot |
| 91 | + | Lift i1, Lift i2 -> Lift (Interval.eval_binary i1 b i2) |
| 92 | + |
| 93 | + let exclude (i: int) (x: t): t = |
| 94 | + failwith "TODO" |
| 95 | +end |
0 commit comments