mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-11 21:48:50 -05:00
88 lines
2.7 KiB
OCaml
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
|