term.mli 12.5 KB
Newer Older
Andrei Paskevich's avatar
Andrei Paskevich committed
1 2 3 4 5 6 7 8 9 10
(********************************************************************)
(*                                                                  *)
(*  The Why3 Verification Platform   /   The Why3 Development Team  *)
(*  Copyright 2010-2012   --   INRIA - CNRS - Paris-Sud 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.                           *)
(*                                                                  *)
(********************************************************************)
11

François Bobot's avatar
François Bobot committed
12
open Stdlib
13
open Ident
14
open Ty
15

16 17
(** Terms and Formulas *)

Simon Cruanes's avatar
Simon Cruanes committed
18
(** {2 Variable symbols} *)
19 20

type vsymbol = private {
21
  vs_name : ident;
22
  vs_ty   : ty;
23 24
}

25 26 27
module Mvs : Extmap.S with type key = vsymbol
module Svs : Extset.S with module M = Mvs
module Hvs : Exthtbl.S with type key = vsymbol
Andrei Paskevich's avatar
Andrei Paskevich committed
28
module Wvs : Weakhtbl.S with type key = vsymbol
29

30
val vs_equal : vsymbol -> vsymbol -> bool
Andrei Paskevich's avatar
Andrei Paskevich committed
31
val vs_hash : vsymbol -> int
32

33
val create_vsymbol : preid -> ty -> vsymbol
34

Simon Cruanes's avatar
Simon Cruanes committed
35
(** {2 Function and predicate symbols} *)
36

37 38 39
type lsymbol = private {
  ls_name   : ident;
  ls_args   : ty list;
40
  ls_value  : ty option;
41
  ls_opaque : Stv.t;
42 43
}

44 45 46
module Mls : Extmap.S with type key = lsymbol
module Sls : Extset.S with module M = Mls
module Hls : Exthtbl.S with type key = lsymbol
Andrei Paskevich's avatar
Andrei Paskevich committed
47
module Wls : Weakhtbl.S with type key = lsymbol
48

49
val ls_equal : lsymbol -> lsymbol -> bool
Andrei Paskevich's avatar
Andrei Paskevich committed
50
val ls_hash : lsymbol -> int
51

52 53 54
val create_lsymbol : ?opaque:Stv.t -> preid -> ty list -> ty option -> lsymbol
val create_fsymbol : ?opaque:Stv.t -> preid -> ty list -> ty -> lsymbol
val create_psymbol : ?opaque:Stv.t -> preid -> ty list -> lsymbol
55

56 57
val ls_ty_freevars : lsymbol -> Stv.t

Simon Cruanes's avatar
Simon Cruanes committed
58
(** {2 Exceptions} *)
59

60
exception EmptyCase
61
exception DuplicateVar of vsymbol
Andrei Paskevich's avatar
Andrei Paskevich committed
62
exception UncoveredVar of vsymbol
63
exception BadArity of lsymbol * int * int
64 65
exception FunctionSymbolExpected of lsymbol
exception PredicateSymbolExpected of lsymbol
66

Simon Cruanes's avatar
Simon Cruanes committed
67
(** {2 Patterns} *)
68 69 70

type pattern = private {
  pat_node : pattern_node;
Andrei Paskevich's avatar
Andrei Paskevich committed
71
  pat_vars : Svs.t;
72 73
  pat_ty   : ty;
  pat_tag  : int;
74 75 76 77 78
}

and pattern_node = private
  | Pwild
  | Pvar of vsymbol
79
  | Papp of lsymbol * pattern list
Andrei Paskevich's avatar
Andrei Paskevich committed
80
  | Por  of pattern * pattern
81
  | Pas  of pattern * vsymbol
82

83
val pat_equal : pattern -> pattern -> bool
Andrei Paskevich's avatar
Andrei Paskevich committed
84
val pat_hash : pattern -> int
85

MARCHE Claude's avatar
MARCHE Claude committed
86
(** Smart constructors for patterns *)
87 88 89

val pat_wild : ty -> pattern
val pat_var : vsymbol -> pattern
90
val pat_app : lsymbol -> pattern list -> ty -> pattern
Andrei Paskevich's avatar
Andrei Paskevich committed
91
val pat_or  : pattern -> pattern -> pattern
92 93
val pat_as  : pattern -> vsymbol -> pattern

MARCHE Claude's avatar
MARCHE Claude committed
94
(** Generic traversal functions *)
95

96 97
val pat_map : (pattern -> pattern) -> pattern -> pattern
val pat_fold : ('a -> pattern -> 'a) -> 'a -> pattern -> 'a
98 99
val pat_all : (pattern -> bool) -> pattern -> bool
val pat_any : (pattern -> bool) -> pattern -> bool
100

MARCHE Claude's avatar
MARCHE Claude committed
101
(** {2 Terms and Formulas} *)
Andrei Paskevich's avatar
minor  
Andrei Paskevich committed
102

103
type quant =
104 105
  | Tforall
  | Texists
106

107
type binop =
108 109 110 111
  | Tand
  | Tor
  | Timplies
  | Tiff
112

113
type term = private {
114
  t_node  : term_node;
115
  t_ty    : ty option;
116
  t_label : Slab.t;
117
  t_loc   : Loc.position option;
118
  t_vars  : int Mvs.t;
119
  t_tag   : int;
120 121 122 123
}

and term_node = private
  | Tvar of vsymbol
124
  | Tconst of Number.constant
125
  | Tapp of lsymbol * term list
126
  | Tif of term * term * term
127
  | Tlet of term * term_bound
Andrei Paskevich's avatar
Andrei Paskevich committed
128
  | Tcase of term * term_branch list
129 130 131 132 133 134 135
  | Teps of term_bound
  | Tquant of quant * term_quant
  | Tbinop of binop * term * term
  | Tnot of term
  | Ttrue
  | Tfalse

136
and term_bound
137
and term_branch
138
and term_quant
139

140
and trigger = term list list
141

142 143 144
module Mterm : Extmap.S with type key = term
module Sterm : Extset.S with module M = Mterm
module Hterm : Exthtbl.S with type key = term
Andrei Paskevich's avatar
Andrei Paskevich committed
145

146
val t_equal : term -> term -> bool
147
val t_hash : term -> int
148

149
(** Bindings *)
150

151 152 153 154
(** close bindings *)

val t_close_bound : vsymbol -> term -> term_bound
val t_close_branch : pattern -> term -> term_branch
155
val t_close_quant : vsymbol list -> trigger -> term -> term_quant
156 157 158 159 160

(** open bindings *)

val t_open_bound : term_bound -> vsymbol * term
val t_open_branch : term_branch -> pattern * term
161
val t_open_quant : term_quant -> vsymbol list * trigger * term
162 163 164 165 166 167 168 169 170

(** open bindings with optimized closing callbacks *)

val t_open_bound_cb :
  term_bound -> vsymbol * term * (vsymbol -> term -> term_bound)

val t_open_branch_cb :
  term_branch -> pattern * term * (pattern -> term -> term_branch)

171 172 173
val t_open_quant_cb :
  term_quant -> vsymbol list * trigger * term *
              (vsymbol list -> trigger -> term -> term_quant)
174

175
(** Type checking *)
176 177 178 179 180

exception TermExpected of term
exception FmlaExpected of term

val t_type : term -> ty
181 182
(** [t_type t] checks that [t] is value-typed and returns its type *)

183
val t_prop : term -> term
184 185 186 187 188
(** [t_prop t] checks that [t] is prop-typed and returns [t] *)

val t_ty_check : term -> ty option -> unit
(** [t_ty_check t ty] checks that the type of [t] is [ty] *)

189 190
(** Smart constructors for terms and formulas *)

191 192
val t_app  : lsymbol -> term list -> ty option -> term
val fs_app : lsymbol -> term list -> ty -> term
193
val ps_app : lsymbol -> term list -> term
194 195

val t_app_infer : lsymbol -> term list -> term
196 197
val ls_arg_inst : lsymbol -> term list -> ty Mtv.t
val ls_app_inst : lsymbol -> term list -> ty option -> ty Mtv.t
198

199
val t_var : vsymbol -> term
200
val t_const : Number.constant -> term
201
val t_if : term -> term -> term -> term
202 203
val t_let : term -> term_bound -> term
val t_case : term -> term_branch list -> term
204 205 206 207 208 209 210 211 212 213 214 215
val t_eps : term_bound -> term
val t_quant : quant -> term_quant -> term
val t_forall : term_quant -> term
val t_exists : term_quant -> term
val t_binary : binop -> term -> term -> term
val t_and : term -> term -> term
val t_or : term -> term -> term
val t_implies : term -> term -> term
val t_iff : term -> term -> term
val t_not : term -> term
val t_true : term
val t_false : term
216

Andrei Paskevich's avatar
Andrei Paskevich committed
217 218 219 220
val t_nat_const : int -> term
(** [t_nat_const n] builds the constant integer term [n],
    n must be non-negative *)

221 222 223 224
val asym_label : label
val t_and_asym : term -> term -> term
val t_or_asym : term -> term -> term

225
val t_let_close : vsymbol -> term -> term -> term
226 227 228 229
val t_eps_close : vsymbol -> term -> term
val t_quant_close : quant -> vsymbol list -> trigger -> term -> term
val t_forall_close : vsymbol list -> trigger -> term -> term
val t_exists_close : vsymbol list -> trigger -> term -> term
230

231
val t_label : ?loc:Loc.position -> Slab.t -> term -> term
232 233
val t_label_add : label -> term -> term
val t_label_copy : term -> term -> term
234

MARCHE Claude's avatar
MARCHE Claude committed
235
(** Constructors with propositional simplification *)
236

237 238
val keep_on_simp_label : label

239
val t_if_simp : term -> term -> term -> term
240
val t_let_simp : term -> term_bound -> term
241 242 243 244 245 246 247 248 249 250 251
val t_quant_simp : quant -> term_quant -> term
val t_forall_simp : term_quant -> term
val t_exists_simp : term_quant -> term
val t_binary_simp : binop -> term -> term -> term
val t_and_simp : term -> term -> term
val t_and_simp_l : term list -> term
val t_or_simp : term -> term -> term
val t_or_simp_l : term list -> term
val t_implies_simp : term -> term -> term
val t_iff_simp : term -> term -> term
val t_not_simp : term -> term
252

253 254 255 256 257
val t_and_asym_simp : term -> term -> term
val t_and_asym_simp_l : term list -> term
val t_or_asym_simp : term -> term -> term
val t_or_asym_simp_l : term list -> term

258
val t_let_close_simp : vsymbol -> term -> term -> term
259 260 261
val t_quant_close_simp : quant -> vsymbol list -> trigger -> term -> term
val t_forall_close_simp : vsymbol list -> trigger -> term -> term
val t_exists_close_simp : vsymbol list -> trigger -> term -> term
262

263
val t_forall_close_merge : vsymbol list -> term -> term
264 265 266
(** [forall_close_merge vs f] puts a universal quantifier over [f];
    merges variable lists if [f] is already universally quantified;
    reuses triggers of [f], if any, otherwise puts no triggers. *)
267

268
(** Built-in symbols *)
269

270
val ps_equ : lsymbol  (* equality predicate *)
271

272 273
val t_equ : term -> term -> term
val t_neq : term -> term -> term
274

275 276
val t_equ_simp : term -> term -> term
val t_neq_simp : term -> term -> term
277

278 279 280 281 282
val fs_bool_true  : lsymbol
val fs_bool_false : lsymbol

val t_bool_true  : term
val t_bool_false : term
283

284 285
val fs_tuple : int -> lsymbol   (* n-tuple *)
val t_tuple : term list -> term
Andrei Paskevich's avatar
Andrei Paskevich committed
286

287
val is_fs_tuple : lsymbol -> bool
288
val is_fs_tuple_id : ident -> int option
Andrei Paskevich's avatar
Andrei Paskevich committed
289

290 291
val fs_func_app : lsymbol  (* value-typed higher-order application *)
val ps_pred_app : lsymbol  (* prop-typed higher-order application *)
292

293
val t_func_app : term -> term -> term
294
val t_pred_app : term -> term -> term
295

296
val t_func_app_l : term -> term list -> term
297
val t_pred_app_l : term -> term list -> term
298

299
(** {2 Term library} *)
300

301
(** One-level (non-recursive) term traversal *)
302

303 304 305
val t_map : (term -> term) -> term -> term
val t_fold : ('a -> term -> 'a) -> 'a -> term -> 'a
val t_map_fold : ('a -> term -> 'a * term) -> 'a -> term -> 'a * term
306

307 308
val t_all : (term -> bool) -> term -> bool
val t_any : (term -> bool) -> term -> bool
309

310
(** Special maps *)
311

312 313
val t_map_simp : (term -> term) -> term -> term
(** [t_map_simp] reconstructs the term using simplification constructors *)
314

315 316
val t_map_sign : (bool -> term -> term) -> bool -> term -> term
(** [t_map_sign] passes a polarity parameter, unfolds if-then-else and iff *)
317

318 319
val t_map_cont : ((term -> 'a) -> term -> 'a) -> (term -> 'a) -> term -> 'a
(** [t_map_cont] is [t_map] in continuation-passing style *)
320

321
val list_map_cont: (('a -> 'b) -> 'c -> 'b) -> ('a list -> 'b) -> 'c list -> 'b
322

323
(** Trigger traversal *)
324

325 326 327 328
val tr_equal : trigger -> trigger -> bool
val tr_map : (term -> term) -> trigger -> trigger
val tr_fold : ('a -> term -> 'a) -> 'a -> trigger -> 'a
val tr_map_fold : ('a -> term -> 'a * term) -> 'a -> trigger -> 'a * trigger
329

330
(** Traversal with separate functions for value-typed and prop-typed terms *)
331

332
module TermTF : sig
333

334 335 336 337 338 339 340
  val t_select : (term -> 'a) -> (term -> 'a) -> term -> 'a
  (** [t_select fnT fnF t] is [fnT t] if [t] is a value, [fnF t] otherwise *)

  val t_selecti : ('a -> term -> 'b) -> ('a -> term -> 'b) -> 'a -> term -> 'b
  (** [t_selecti fnT fnF acc t] is [t_select (fnT acc) (fnF acc) t] *)

  val t_map : (term -> term) -> (term -> term) -> term -> term
341
  (** [t_map fnT fnF = t_map (t_select fnT fnF)] *)
342 343

  val t_fold : ('a -> term -> 'a) -> ('a -> term -> 'a) -> 'a -> term -> 'a
344
  (** [t_fold fnT fnF = t_fold (t_selecti fnT fnF)] *)
Jean-Christophe Filliâtre's avatar
Jean-Christophe Filliâtre committed
345 346

  val t_map_fold : ('a -> term -> 'a * term) ->
347 348 349 350 351 352 353
    ('a -> term -> 'a * term) -> 'a -> term -> 'a * term

  val t_all : (term -> bool) -> (term -> bool) -> term -> bool
  val t_any : (term -> bool) -> (term -> bool) -> term -> bool

  val t_map_simp : (term -> term) -> (term -> term) -> term -> term

Jean-Christophe Filliâtre's avatar
Jean-Christophe Filliâtre committed
354
  val t_map_sign : (bool -> term -> term) ->
355 356
    (bool -> term -> term) -> bool -> term -> term

Jean-Christophe Filliâtre's avatar
Jean-Christophe Filliâtre committed
357
  val t_map_cont : ((term -> 'a) -> term -> 'a) ->
358 359 360 361 362
    ((term -> 'a) -> term -> 'a) -> (term -> 'a) -> term -> 'a

  val tr_map : (term -> term) -> (term -> term) -> trigger -> trigger

  val tr_fold : ('a -> term -> 'a) -> ('a -> term -> 'a) -> 'a -> trigger -> 'a
Jean-Christophe Filliâtre's avatar
Jean-Christophe Filliâtre committed
363 364

  val tr_map_fold : ('a -> term -> 'a * term) ->
365
    ('a -> term -> 'a * term) -> 'a -> trigger -> 'a * trigger
366
end
367

368
(** Map/fold over free variables *)
369 370 371 372 373 374

val t_v_map : (vsymbol -> term) -> term -> term
val t_v_fold : ('a -> vsymbol -> 'a) -> 'a -> term -> 'a
val t_v_all : (vsymbol -> bool) -> term -> bool
val t_v_any : (vsymbol -> bool) -> term -> bool

375
(** Variable substitution *)
376 377 378 379

val t_subst : term Mvs.t -> term -> term
val t_subst_single : vsymbol -> term -> term -> term

380 381
val t_ty_subst : ty Mtv.t -> term Mvs.t -> term -> term

382
(** Find free variables and type variables *)
383

384
val t_freevars    : int Mvs.t -> term -> int Mvs.t
385
val t_ty_freevars : Stv.t -> term -> Stv.t
386

387
(** Map/fold over types and logical symbols in terms and patterns *)
388

389 390 391
val t_gen_map :
  (ty -> ty) -> (lsymbol -> lsymbol) -> vsymbol Mvs.t -> term -> term

392 393 394 395 396 397
val t_s_map : (ty -> ty) -> (lsymbol -> lsymbol) -> term -> term
val t_s_fold : ('a -> ty -> 'a) -> ('a -> lsymbol -> 'a) -> 'a -> term -> 'a

val t_s_all : (ty -> bool) -> (lsymbol -> bool) -> term -> bool
val t_s_any : (ty -> bool) -> (lsymbol -> bool) -> term -> bool

398
val t_ty_map : (ty -> ty) -> term -> term
399 400
val t_ty_fold : ('a -> ty -> 'a) -> 'a -> term -> 'a

401 402 403 404
(* Map/fold over applications in terms (but not in patterns!) *)

val t_app_map :
  (lsymbol -> ty list -> ty option -> lsymbol) -> term -> term
405

406 407 408 409
val t_app_fold :
  ('a -> lsymbol -> ty list -> ty option -> 'a) -> 'a -> term -> 'a

(** Equality modulo alpha *)
410 411

val t_equal_alpha : term -> term -> bool
Andrei Paskevich's avatar
minor  
Andrei Paskevich committed
412

413
module Hterm_alpha : Exthtbl.S with type key = term
414

415
(** Subterm occurrence check and replacement *)
416

417 418
val t_occurs : term -> term -> bool
val t_occurs_alpha : term -> term -> bool
419

420 421
val t_replace : term -> term -> term -> term
val t_replace_alpha : term -> term -> term -> term
422