Mlsem_common.REnvRefinement environment: a conjunction of constraints "variable v has type t", used to narrow a typing environment at a given program point.
Unlike Env, an REnv is partial: a variable it does not bind is unconstrained, i.e. implicitly bound to any (see REnv.find'). So the empty environment is the trivially true constraint, and an environment binding some variable to empty is unsatisfiable. This convention explains the approximations below.
include Env.Env with type ty := Mlsem_types.Ty.tval empty : tval is_empty : t -> boolWhether the environment has no binding at all.
val singleton : Variable.t -> Mlsem_types.Ty.t -> tval construct : (Variable.t * Mlsem_types.Ty.t) list -> tval add : Variable.t -> Mlsem_types.Ty.t -> t -> tBinds a variable that is not already bound; use replace otherwise.
val replace : Variable.t -> Mlsem_types.Ty.t -> t -> tBinds a variable, overriding any previous binding.
val domain : t -> Variable.t listval bindings : t -> (Variable.t * Mlsem_types.Ty.t) listval mem : Variable.t -> t -> boolval find : Variable.t -> t -> Mlsem_types.Ty.tval find_opt : Variable.t -> t -> Mlsem_types.Ty.t optionval rm : Variable.t -> t -> tval rms : Variable.t list -> t -> tval restrict : Variable.t list -> t -> tval map : (Mlsem_types.Ty.t -> Mlsem_types.Ty.t) -> t -> tval filter : (Variable.t -> Mlsem_types.Ty.t -> bool) -> t -> tval tvars : t -> Mlsem_types.MVarSet.tAn over-approximation of the type variables occurring in the environment: it is maintained incrementally and not recomputed when a binding is combined with another. Sound wherever it is used to build a set of monomorphic variables, but not a reliable "occurs" test.
leq env1 env2 holds when env1 is at least as precise as env2: it binds at least the same variables, at smaller types.
val show : t -> stringval pp : Stdlib.Format.formatter -> t -> unitval find' : Variable.t -> t -> Mlsem_types.Ty.tLike find, returning any instead of raising Not_found for an unbound variable. This is the reading that matches the partiality of an REnv.
Negation, as a disjunction: negating a conjunction of constraints yields one alternative per constraint. The empty environment (true) negates to the empty list (false).
Over-approximation of the disjunction of two refinements: a variable constrained in only one of them becomes unconstrained, since nothing can be assumed about it in the other branch.
neg followed by disj_approx; None represents the unsatisfiable refinement, which disj_approx cannot express.