sidekick/src/th-data/Sidekick_th_data.mli

88 lines
2.7 KiB
OCaml

(** Theory for datatypes. *)
(** Datatype-oriented view of terms.
- ['c] is the representation of constructors
- ['t] is the representation of terms
*)
type ('c,'t) data_view =
| T_cstor of 'c * 't IArray.t (** [T_cstor (c,args)] is the term [c(args)] *)
| T_select of 'c * int * 't
(** [T_select (c,i,u)] means the [i]-th argument of [u], which should
start with constructor [c] *)
| T_is_a of 'c * 't (** [T_is_a (c,u)] means [u] starts with constructor [c] *)
| T_other of 't (** non-datatype term *)
(* TODO: use ['ts] rather than IArray? *)
(** View of types in a way that is directly useful for the theory of datatypes *)
type ('c, 'ty) data_ty_view =
| Ty_arrow of 'ty Iter.t * 'ty
| Ty_app of {
args: 'ty Iter.t;
}
| Ty_data of {
cstors: 'c;
}
| Ty_other
(** Argument to the functor *)
module type ARG = sig
module S : Sidekick_core.SOLVER
(** Constructor symbols.
A constructor is an injective symbol, part of a datatype (or "sum type").
For example, in [type option a = Some a | None],
the constructors are [Some] and [None]. *)
module Cstor : sig
type t
(** Constructor *)
val ty_args : t -> S.T.Ty.t Iter.t
(** Type arguments, for a polymorphic constructor *)
val pp : t Fmt.printer
val equal : t -> t -> bool
(** Comparison *)
end
val as_datatype : S.T.Ty.t -> (Cstor.t Iter.t, S.T.Ty.t) data_ty_view
(** Try to view type as a datatype (with its constructors) *)
val view_as_data : S.T.Term.t -> (Cstor.t, S.T.Term.t) data_view
(** Try to view term as a datatype term *)
val mk_cstor : S.T.Term.state -> Cstor.t -> S.T.Term.t IArray.t -> S.T.Term.t
(** Make a constructor application term *)
val mk_is_a: S.T.Term.state -> Cstor.t -> S.T.Term.t -> S.T.Term.t
(** Make a [is-a] term *)
val mk_sel : S.T.Term.state -> Cstor.t -> int -> S.T.Term.t -> S.T.Term.t
(** Make a selector term *)
val mk_eq : S.T.Term.state -> S.T.Term.t -> S.T.Term.t -> S.T.Term.t
(** Make a term equality *)
val ty_is_finite : S.T.Ty.t -> bool
(** Is the given type known to be finite? For example a finite datatype
(an "enum" in C parlance), or [Bool], or [Array Bool Bool]. *)
val ty_set_is_finite : S.T.Ty.t -> bool -> unit
(** Modify the "finite" field (see {!ty_is_finite}) *)
(* TODO: should we store this ourself? would be simpler… *)
val proof_isa_split : S.T.Ty.t -> S.T.Term.t Iter.t -> S.P.t
val proof_isa_disj : S.T.Ty.t -> S.T.Term.t -> S.T.Term.t -> S.P.t
val proof_cstor_inj : Cstor.t -> int -> S.T.Term.t list -> S.T.Term.t list -> S.P.t
end
module type S = sig
module A : ARG
val theory : A.S.theory
(** A theory that can be added to {!A.S} to perform datatype reasoning. *)
end
module Make(A : ARG) : S with module A = A