aboutsummaryrefslogtreecommitdiffstats
path: root/src/trace/smtBtype.ml
blob: f3245ead78cc0177c96438812ca8e6733e40a4ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
open SmtMisc
open CoqTerms

(** Syntaxified version of Coq type *)

type indexed_type = Term.constr gen_hashed

let dummy_indexed_type i = {index = i; hval = Term.mkProp}
let indexed_type_index i = i.index
let indexed_type_hval i = i.hval

type btype =
  | TZ
  | Tbool
  | Tpositive
  | Tindex of indexed_type

let index_tbl = Hashtbl.create 17

let index_to_coq i =
  try Hashtbl.find index_tbl i
  with Not_found ->
    let interp = mklApp cTindex [|mkInt i|] in
    Hashtbl.add index_tbl i interp;
    interp

let indexed_type_of_int i =
  {index = i; hval = index_to_coq i }
      
let equal t1 t2 =
  match t1,t2 with
  | Tindex i, Tindex j -> i.index == j.index
  | _ -> t1 == t2

let to_coq = function
  | TZ -> Lazy.force cTZ
  | Tbool -> Lazy.force cTbool
  | Tpositive -> Lazy.force cTpositive
  | Tindex i -> index_to_coq i.index

let to_string = function
  | TZ -> "Int"
  | Tbool -> "Bool"
  | Tpositive -> "Int"
  | Tindex i -> "Tindex_" ^ string_of_int i.index

let to_smt fmt b = Format.fprintf fmt "%s" (to_string b)

(* reify table *)
type reify_tbl =
  { mutable count : int;
    tbl : (Term.constr, btype) Hashtbl.t;
    mutable cuts : (Structures.names_id_t * Term.types) list
  }

let create () =
  let htbl = Hashtbl.create 17 in
  Hashtbl.add htbl (Lazy.force cZ) TZ;
  Hashtbl.add htbl (Lazy.force cbool) Tbool;
  (* Hashtbl.add htbl (Lazy.force cpositive) Tpositive; *)
  { count = 0;
    tbl = htbl;
    cuts = [] }

let get_cuts reify = reify.cuts

let declare reify t typ_eqb =
  (* TODO: allows to have only typ_eqb *)
  assert (not (Hashtbl.mem reify.tbl t));
  let res = Tindex {index = reify.count; hval = typ_eqb} in
  Hashtbl.add reify.tbl t res;
  reify.count <- reify.count + 1;
  res

let of_coq reify t =
  try
    Hashtbl.find reify.tbl t
  with | Not_found ->
          let n = string_of_int (List.length reify.cuts) in
          let eq_name = Names.id_of_string ("eq"^n) in
          let eq_var = Term.mkVar eq_name in

          let eq_ty = Term.mkArrow t (Term.mkArrow t (Lazy.force cbool)) in

          let eq = mkName "eq" in
          let x = mkName "x" in
          let y = mkName "y" in
          let req = Term.mkRel 3 in
          let rx = Term.mkRel 2 in
          let ry = Term.mkRel 1 in
          let refl_ty = Term.mkLambda (eq, eq_ty, Term.mkProd (x,t,Term.mkProd (y,t,mklApp creflect [|mklApp ceq [|t;rx;ry|]; Term.mkApp (req, [|rx;ry|])|]))) in

          let pair_ty = mklApp csigT [|eq_ty; refl_ty|] in

          reify.cuts <- (eq_name, pair_ty)::reify.cuts;
          let ce = mklApp ctyp_eqb_of_typ_eqb_param [|t; eq_var|] in
          declare reify t ce

let interp_tbl reify =
  let t = Array.make (reify.count + 1) (Lazy.force cunit_typ_eqb) in
  let set _ = function
    | Tindex it -> t.(it.index) <- it.hval
    | _ -> () in
  Hashtbl.iter set reify.tbl;
  Structures.mkArray (Lazy.force ctyp_eqb, t)

let to_list reify =
  let set _ t acc = match t with
    | Tindex it -> (it.index,it)::acc
    | _ -> acc in
  Hashtbl.fold set reify.tbl []

let interp_to_coq reify = function
  | TZ -> Lazy.force cZ
  | Tbool -> Lazy.force cbool
  | Tpositive -> Lazy.force cpositive
  | Tindex c -> mklApp cte_carrier [|c.hval|]