Description
Agda throws away solutions when pruning arguments containing variables of record Unit
type.
Here are some examples.
module Prune where
record Unit : Set where
constructor tt
postulate F : Set → Set
postulate a : Set → Unit → Set
postulate kA : {M : Set → Set → Set} →
((x : Set) (y : Unit) → F (M x (a x y))) →
Set
postulate kB : {M : Set → Set → Set} →
((x : Set) (y : Unit) → F (M x (a x y))) →
((x : Set) (y : Set) → F (M x y)) →
Set
postulate F' : (A : Set) → F A
-- Some problems
-- ?M : Set → Set → Set
---------------------------------
K1 : Set
K1 = kA (\x y → F' (a x tt))
---------------------------------
-- Unification problem: ∀(x:Set)(y:Unit). ?M x (a x y) ≈ a x tt
-- Agda solution: ?M := \ x _ → a x tt
-- Expected: No solution, because (?M := \ _ b → b is also a solution)
---------------------------------
---------------------------------
K2 : Set
K2 = kB (\x y → F' (a x tt))
(\x y → F' (a x tt))
---------------------------------
-- Unification problem: ∀(x:Set)(y:Unit). ?M x (a x y) ≈ a x tt
-- ∧ ∀(x:Set)(y:Set). ?M x y ≈ a x tt
-- Agda solution: ?M := \x _ → a x tt
-- Expected solution: [idem.]
--------------------------------
--------------------------------
K3 : Set
K3 = kB {\x y → y}
(\x y → F' (a x tt))
(\x y → F' y)
--------------------------------
-- Unification problem: ∀(x:Set)(y:Unit). (\x y → y) x (a x y) ≈ a x tt
-- ∧ ∀(x:Set)(y:Set). (\x y → y) x y ≈ y
-- Agda solution: OK
-- Expected solution: OK
--------------------------------
--------------------------------
K4 : Set
K4 = kB (\x y → F' (a x tt))
(\x y → F' y)
--------------------------------
-- Unification problem: ∀(x:Set)(y:Unit). ?M x (a x y) ≈ a x tt
-- ∧ ∀(x:Set)(y:Set). ?M x y ≈ y
-- Agda solution: ERROR (y ≠ a x tt : Set)
-- Expected solution: ?M := \x y → y (cf. `K3`)
--------------------------------
Tested with Agda version 2.6.0-c284008
. Here is the offending function:
I think that the behaviour of Agda when typechecking K1
, and specially K4
is a bug. The problem is that the meta argument a x y
gets pruned away for having a free y
. But, because of it's type, y
is not really free.
Pruning non-Miller arguments¹ is however necessary to type-check even the current standard-library, so a blanket removal is not possible. So it should be done in such a way that variables of potentially singleton type² are not considered "bad".
¹. For example, applications of neutral constants, like type constructors or postulates.
². That is, variables that are definitionally equal to terms that do not contain them.