Guarantees

Reading settings

Look

Mode

Definitions

Proofs

Imports

Arguments

References

References open

Saved in this browser.

ModulesGuarantees

Modules

Spec

Types6Runtime6Witnesses4

RFC0001

Overview0Constraints17TypeCase37Representation3Discussion0
On this page

On this page

FalsifiedRepresentationGuaranteesConstraintsTypeCase

Guarantees

Falsified

Clef.RFC0001.Representation

Guarantees

Clef.RFC0001.Constraints

Entailment is exactly preservation of satisfaction.

Rests on Types.tycon_eq_dec, Types.tycon

The subset test accepts a use of a constrained variable if and only if every type the variable can be instantiated to satisfies the required constraint. It rejects nothing sound and accepts nothing unsound.

Intersecting two constraints loses no information.

Rests on Types.tycon_eq_dec, Types.tycon

A type satisfies the intersection if and only if it satisfies both constraints, so replacing two constraints by their intersection changes no program's meaning.

An empty intersection admits no type.

Rests on Types.tycon_eq_dec, Types.tycon

When two constraints share no member, no instantiation satisfies both, so reporting an error is the only sound outcome.

Clef.RFC0001.TypeCase

A definition that checks is well typed at every instantiation.

Rests on Witnesses.witness, Types.tycon_eq_dec, Types.tycon, Witnesses.op

This is derived satisfaction. When the check passes at the definition, every type that satisfies the constraint yields a specialization with the declared type. A call site is never the first place where an operation on the constrained variable is found unsupported.

Narrowing a constraint keeps a definition valid.

Rests on Witnesses.witness, Types.tycon_eq_dec, Types.tycon, Witnesses.op

A body that checks against a member set checks against every set that entails it. Removing a member from a constraint never breaks the definition, so only adding one can.

An operation is accepted exactly when every member has a witness for it.

Rests on Witnesses.witness, Types.tycon_eq_dec, Types.tycon, Witnesses.op

A body that applies one operation to its parameter checks if and only if each member has a witness for that operation with the declared result type. The result type may mention the variable, which is how x + x has type 'T at both int and float.

A specialization computes what the definition means, without being told the type.

Rests on Types.tycon_eq_dec, Types.tycon, Witnesses.op, Runtime.atom, Witnesses.apply

Whenever a body specializes at a type, the specialization returns exactly what the reference meaning returns at that type, on every input. The reference meaning inspects the instantiating type and the specialization has no access to it. The static type-case is therefore erased completely: no run-time test, tag or type argument is needed to implement it.

A typed specialization runs to a value of its type.

Rests on Witnesses.witness_sound, Witnesses.witness, Types.tycon, Witnesses.op, Runtime.atom, Witnesses.apply

Evaluation of a specialization that has a type never gets stuck, and the value it returns has that type. This rests on the assumption that every witness is implemented at its declared type.

A definition that checks runs to a value at every member.

Rests on Witnesses.witness_sound, Witnesses.witness, Types.tycon_eq_dec, Types.tycon, Witnesses.op, Runtime.atom, Witnesses.apply

Take a definition whose check passes, any type satisfying its constraint, and arguments of the parameter types at that type. The definition's meaning at that type is a value of the declared result type. The check at the definition is all that is needed: nothing is checked again at a call site or at run time.

A body with no type-case is the same code at every instantiation.

Rests on Types.tycon_eq_dec, Types.tycon, Witnesses.op

Its specialization does not depend on the instantiating type. Only a type-case can make a set-constrained definition behave differently per member, so the loss of uniformity is confined to bodies that ask for it.

A body with no type-case cannot observe its instantiation.

Rests on Types.tycon_eq_dec, Types.tycon, Witnesses.op, Runtime.atom, Witnesses.apply

Its meaning is the same at every type, on every input. A set-constrained definition that does not use a type-case is as uniform as an unconstrained one.

A covered body specializes at every member.

Rests on Types.tycon_eq_dec, Types.tycon, Witnesses.op

When each type-case tests every member, saturation finds an arm for every instantiating type that satisfies the constraint. No instantiation is left without code.