| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
Agda.TypeChecking.Rules.LHS.Unify
Description
Unification algorithm for specializing datatype indices, as described in "Unifiers as Equivalences: Proof-Relevant Unification of Dependently Typed Data" by Jesper Cockx, Dominique Devriese, and Frank Piessens (ICFP 2016).
This is the unification algorithm used for checking the left-hand side
of clauses (see Agda.TypeChecking.Rules.LHS), coverage checking (see
Agda.TypeChecking.Coverage) and indirectly also for interactive case
splitting (see Agda.Interaction.MakeCase).
A unification problem (of type UnifyState) consists of:
- A telescope
varTelof free variables, some or all of which are flexible (as indicated byflexVars). - A telescope
eqTelcontaining the types of the equations. - Left- and right-hand sides for each equation:
varTel ⊢ eqLHS : eqTelandvarTel ⊢ eqRHS : eqTel.
The unification algorithm can end in three different ways:
(type UnificationResult):
- A *positive success*
Unifies (tel, sigma, ps)withtel ⊢ sigma : varTel,tel ⊢ eqLHS [ varTel ↦ sigma ] ≡ eqRHS [ varTel ↦ sigma ] : eqTel, andtel ⊢ ps : eqTel. In this case,sigma;psis an *equivalence* between the telescopestelandvarTel(eqLHS ≡ eqRHS). - A *negative success*
NoUnify errmeans that a conflicting equation was found (e.g an equation between two distinct constructors or a cycle). - A *failure*
UnifyStuck errmeans that the unifier got stuck.
The unification algorithm itself consists of two parts:
- A *unification strategy* takes a unification problem and produces a
list of suggested unification rules (of type
UnifyStep). Strategies can be constructed by composing simpler strategies (see for example the definition ofcompleteStrategyAt). - The *unification engine*
unifySteptakes a unification rule and tries to apply it to the given state, writing the result to the UnifyOutput on a success.
The unification steps (of type UnifyStep) are the following:
- *Deletion* removes a reflexive equation
u =?= v : aif the left- and right-hand sideuandvare (definitionally) equal. This rule results in a failure if --without-K is enabled (see "Pattern Matching Without K" by Jesper Cockx, Dominique Devriese, and Frank Piessens (ICFP 2014). - *Solution* solves an equation if one side is (eta-equivalent to) a
flexible variable. In case both sides are flexible variables, the
unification strategy makes a choice according to the
chooseFlexfunction inAgda.TypeChecking.Rules.LHS.Problem. - *Injectivity* decomposes an equation of the form
c us =?= c vs : D pars iswherec : Δc → D pars jsis a constructor of the inductive datatypeDinto a sequence of equationsus =?= vs : delta. In caseDis an indexed datatype, - higher-dimensional unification* is applied (see below).
- *Conflict* detects absurd equations of the form
c₁ us =?= c₂ vs : D pars iswherec₁andc₂are two distinct constructors of the datatypeD. - *Cycle* detects absurd equations of the form
x =?= v : D pars iswherexis a variable of the datatypeDthat occurs strongly rigid inv. - *EtaExpandVar* eta-expands a single flexible variable
x : RwhereRis a (eta-expandable) record type, replacing it by one variable for each field ofR. - *EtaExpandEquation* eta-expands an equation
u =?= v : RwhereRis a (eta-expandable) record type, replacing it by one equation for each field ofR. The left- and right-hand sides of these equations are the projections ofuandv. - *LitConflict* detects absurd equations of the form
l₁ =?= l₂ : Awherel₁andl₂are distinct literal terms. - *StripSizeSuc* simplifies an equation of the form
sizeSuc x =?= sizeSuc y : Sizetox =?= y : Size. - *SkipIrrelevantEquation@ removes an equation between irrelevant terms.
- *TypeConInjectivity* decomposes an equation of the form
D us =?= D vs : Set iwhereDis a datatype. This rule is only used if --injective-type-constructors is enabled.
Higher-dimensional unification (new, does not yet appear in any paper):
If an equation of the form c us =?= c vs : D pars is is encountered where
c : Δc → D pars js is a constructor of an indexed datatype
D pars : Φ → Set ℓ, it is in general unsound to just simplify this
equation to us =?= vs : Δc. For this reason, the injectivity rule in the
paper restricts the indices is to be distinct variables that are bound in
the telescope eqTel. But we can be more general by introducing new
variables ks to the telescope eqTel and equating these to is:
Δ₁(x : D pars is)Δ₂
≃
Δ₁(ks : Φ)(x : D pars ks)(ps : is ≡Φ ks)Δ₂
Since ks are distinct variables, it's now possible to apply injectivity
to the equation x, resulting in the following new equation telescope:
Δ₁(ys : Δc)(ps : is ≡Φ js[Δc ↦ ys])Δ₂
Now we can solve the equations ps by recursively calling the unification
algorithm with flexible variables Δ₁(ys : Δc). This is called
*higher-dimensional unification* since we are unifying equality proofs
rather than terms. If the higher-dimensional unification succeeds, the
resulting telescope serves as the new equation telescope for the original
unification problem.
Synopsis
- type UnificationResult = UnificationResult' (Telescope, PatternSubstitution, [NamedArg DeBruijnPattern])
- data UnificationResult' a
- unifyIndices :: (PureTCM m, MonadBench m, BenchPhase m ~ Phase) => Telescope -> FlexibleVars -> Type -> Args -> Args -> m UnificationResult
Documentation
type UnificationResult = UnificationResult' (Telescope, PatternSubstitution, [NamedArg DeBruijnPattern]) Source #
Result of unifyIndices.
data UnificationResult' a Source #
Constructors
| Unifies a | Unification succeeded. |
| NoUnify NegativeUnification | Terms are not unifiable. |
| UnifyBlocked Blocker | Unification got blocked on a metavariable |
| UnifyStuck [UnificationFailure] | Some other error happened, unification got stuck. |
Instances
Arguments
| :: (PureTCM m, MonadBench m, BenchPhase m ~ Phase) | |
| => Telescope | gamma |
| -> FlexibleVars | flex |
| -> Type | a |
| -> Args | us |
| -> Args | vs |
| -> m UnificationResult |
Unify indices.
In unifyIndices gamma flex a us vs,
usandvsare the argument lists to unify, eliminating typea.gammais the telescope of free variables inusandvs.flexis the set of flexible (instantiable) variabes inusandvs.
The result is the most general unifier of us and vs.