File: clone.ml

package info (click to toggle)
why3 1.8.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 45,028 kB
  • sloc: xml: 185,443; ml: 111,224; ansic: 3,998; sh: 2,578; makefile: 2,568; java: 865; python: 720; javascript: 290; lisp: 205; pascal: 173
file content (253 lines) | stat: -rw-r--r-- 6,803 bytes parent folder | download
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
(********************************************************************)
(*                                                                  *)
(*  The Why3 Verification Platform   /   The Why3 Development Team  *)
(*  Copyright 2010-2025 --  Inria - CNRS - Paris-Saclay University  *)
(*                                                                  *)
(*  This software is distributed under the terms of the GNU Lesser  *)
(*  General Public License version 2.1, with the special exception  *)
(*  on linking described in file LICENSE.                           *)
(********************************************************************)

(*******************

This file builds some MLW modules using the API
In particular, it tests the clone feature
(Inspired from mlw_tree.ml)

******************)

open Why3

let () = Debug.set_flag Debug.stack_trace
let config = Whyconf.init_config None
let main = Whyconf.get_main config
let env = Env.create_env (Whyconf.loadpath main)
open Ptree

let () = Typing.open_file env [] (* empty pathname *)
let mk_ident s = { id_str = s; id_ats = []; id_loc = Loc.dummy_position }
let () = Typing.open_module (mk_ident "Test")


(* Auxiliary functions (same as mlw_tree.ml) *)
let mk_qid l =
  let rec aux l =
    match l with
      | [] -> assert false
      | [x] -> Qident(mk_ident x)
      | x::r -> Qdot(aux r,mk_ident x)
  in
  aux (List.rev l)

let use_import (f, m) =
  let m = mk_ident m in
  let loc = Loc.dummy_position in
  Typing.add_decl loc (Ptree.Duseimport (loc,true, [Qdot (Qident (mk_ident f), m), None]))

let use_int_Int = use_import ("int","Int")

let mk_expr e = { expr_desc = e; expr_loc = Loc.dummy_position }

let mk_term t = { term_desc = t; term_loc = Loc.dummy_position }

let mk_pat p = { pat_desc = p; pat_loc = Loc.dummy_position }
let pat_var id = mk_pat (Pvar id)

let mk_var id = mk_term (Tident (Qident id))

let param0 = [Loc.dummy_position, None, false, Some (PTtuple [])]
let param1 id ty = [Loc.dummy_position, Some id, false, Some ty]

let mk_const i =
  Constant.(ConstInt Number.{ il_kind = ILitDec; il_int = BigInt.of_int i })

let mk_tconst i = mk_term (Tconst (mk_const i))

let mk_econst i = mk_expr (Econst (mk_const i))

let mk_tapp f l = mk_term (Tidapp(f,l))

let mk_eapp f l = mk_expr (Eidapp(f,l))

let mk_evar x = mk_expr(Eident(Qident x))

let eq_symb = mk_qid [Ident.op_infix "="]
let int_type_id = mk_qid ["int"]
let int_type = PTtyapp(int_type_id,[])

let a = mk_ident "a"

(* type a = < range 22 46 > *)
let type_a : Ptree.decl =
  let c22 = BigInt.of_int 22 in
  let c46 = BigInt.of_int 46 in
  Dtype [{
    td_loc = Loc.dummy_position;
    td_ident = a;
    td_params = [];
    td_vis = Public;
    td_mut = false;
    td_inv = [];
    td_wit = None;
    td_def = TDrange (c22, c46);
  }]

(*
  let f2 (b : 'a) =
     ensures {result = false}
     true
*)
let d2 : Ptree.decl =
  let id_b = mk_ident "_b" in
  let pre = mk_term Ttrue in
  let result = mk_ident "result" in
  let post = mk_tapp eq_symb [mk_var result; mk_term Tfalse] in
  let spec = {
    sp_pre = [pre];
    sp_post = [Loc.dummy_position,[pat_var result,post]];
    sp_xpost = [];
    sp_reads = [];
    sp_writes = [];
    sp_alias = [];
    sp_variant = [];
    sp_checkrw = false;
    sp_diverge = false;
    sp_partial = false;
  }
  in
  let body: expr = mk_expr Etrue in
  let f1 =
    Efun(param1 id_b (PTtyvar a), None,  mk_pat Pwild,
         Ity.MaskVisible, spec, body)
  in
  Dlet(mk_ident "f2",false,Expr.RKnone, mk_expr f1)

(*
  let f3 (b : a) =
     ensures {a'int b  = 42}
     true
*)
let d3 : Ptree.decl =
  let id_b = mk_ident "b" in
  let pre = mk_term Ttrue in
  let a_int = mk_qid ["a'int"] in
  let result = mk_ident "_result" in
  let post = mk_tapp eq_symb [mk_tapp a_int [mk_var id_b];
                              mk_tconst 42] in
  let spec = {
    sp_pre = [pre];
    sp_post = [Loc.dummy_position,[pat_var result,post]];
    sp_xpost = [];
    sp_reads = [];
    sp_writes = [];
    sp_alias = [];
    sp_variant = [];
    sp_checkrw = false;
    sp_diverge = false;
    sp_partial = false;
  }
  in
  let body: expr = mk_evar id_b in
  let f1 =
    Efun(param1 id_b (PTtyapp (Qident a, [])), None,  mk_pat Pwild,
         Ity.MaskVisible, spec, body)
  in
  Dlet(mk_ident "f3",false,Expr.RKnone, mk_expr f1)



(*
  let f1 (b : a) =
    requires {a'int b = 42}
    ensures {a'int result = a'int b}
    (42:a)
*)
let d1 : Ptree.decl =
  let id_b = mk_ident "b" in
  let a_int = mk_qid ["a'int"] in
  let pre = mk_tapp eq_symb [mk_tapp a_int [mk_var id_b];
                             mk_tconst 42] in
  let result = mk_ident "result" in
  let post = mk_tapp eq_symb [mk_tapp a_int [mk_var result];
                              mk_tapp a_int [mk_var id_b]] in
  let spec = {
    sp_pre = [pre];
    sp_post = [Loc.dummy_position,[pat_var result,post]];
    sp_xpost = [];
    sp_reads = [];
    sp_writes = [];
    sp_alias = [];
    sp_variant = [];
    sp_checkrw = false;
    sp_diverge = false;
    sp_partial = false;
  }
  in
  let body: expr = mk_expr (Ecast (mk_econst 42, PTtyapp (Qident a, []))) in
  let f1 =
    Efun(param1 id_b (PTtyapp (Qident a, [])), None,  mk_pat Pwild,
         Ity.MaskVisible, spec, body)
  in
  Dlet(mk_ident "f1",false,Expr.RKnone, mk_expr f1)


(* Add those declarations *)
let () = Typing.add_decl Loc.dummy_position type_a
let () = Typing.add_decl Loc.dummy_position d2
let () = Typing.add_decl Loc.dummy_position d3
let () = Typing.add_decl Loc.dummy_position d1

let () = Typing.close_module Loc.dummy_position

(* New module is clone of this one *)
let () = Typing.open_module (mk_ident "Test1")

(*
module Test1
  clone Test as T
end
*)
let clone_decl : Ptree.decl =
  Dcloneimport (Loc.dummy_position, false, Qident (mk_ident "Test"), Some (mk_ident "T"),[])

let () = Typing.add_decl Loc.dummy_position clone_decl

let () = Typing.close_module Loc.dummy_position

(* End of file *)
let mods : Pmodule.pmodule Wstdlib.Mstr.t = Typing.close_file ()

open Format

let () =
  printf "Theory are:@.";
  Wstdlib.Mstr.iter
    (fun _ m ->
      printf "%a@." Pretty.print_theory m.Pmodule.mod_theory) mods

(* Only use of this is to test clone_export *)
let auto_clone task th =
  Task.clone_export task th Theory.empty_inst

let my_tasks : Task.task list =
  let mods =
    Wstdlib.Mstr.fold
      (fun _ m acc ->
        let th = m.Pmodule.mod_theory in
        (* Automatically clone all theories *)
        let task =
          auto_clone None th
        in
        List.rev_append
          (Task.split_theory m.Pmodule.mod_theory None task) acc)
      mods []
  in
  List.rev mods

let () =
  printf "Tasks are:@.";
  let _ =
    List.fold_left
      (fun i t -> printf "@[<v 0>== Task %d ==@\n@\n%a@]@." i Pretty.print_task t; i+1)
      1 my_tasks
  in ()