Skip to main content

check_positivity_resolved

Function check_positivity_resolved 

Source
pub fn check_positivity_resolved(
    ctx: &Context,
    inductive: &str,
    constructor: &str,
    ty: &Term,
) -> KernelResult<()>
Expand description

Strict positivity with every REFERENCE resolved — the paradox fence that a definitional alias cannot walk around.

check_positivity reads the constructor type as written, so a name is an occurrence of the inductive only when it is SPELLED as the inductive. That is not a property of the type, it is a property of the spelling, and δ makes the two different things:

Inductive Bad : Type 0                 -- no constructors yet
Definition Negate : Prop := Bad -> False
Constructor cons : Negate -> Bad       -- `Bad` does not literally occur in `Negate`

Negate is Bad → False up to δ, so cons is the Russell constructor (Bad → False) → Bad — and λx. match x with | cons f => f (cons f) then inhabits Bad → False, which applied to its own cons inhabits False. No fixpoint and no recursor are needed: a bare Term::Match does it, so no later gate can catch what this one lets past. The blind check accepts it because occurs_in asks whether the STRING “Bad” appears.

This entry point answers the same four questions about the same four shapes, but resolves a reference to a transparent definition (or a universe-polymorphic one) before deciding whether the inductive occurs in it and whether an occurrence is a legitimate recursive one. Both directions fail SAFE: a reference whose unfolding cannot be decided counts as an occurrence (so the constructor is refused), and never as a recursive one.