New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Occurs check does not properly handle singleton type #5837
Comments
Here another variant of this issue that involves a variable rather than a postulate: open import Agda.Builtin.Bool
open import Agda.Builtin.Unit
open import Agda.Builtin.Equality
data ⊥ : Set where
T : Bool → Set
T true = ⊤
T false = ⊥
postulate
F : ⊤ → Set
mutual
X : Set
X = _
solve : {Y : (b : Bool) → T b} → X ≡ F (Y true)
solve = refl
{- ERROR:
Cannot instantiate the metavariable _8 to solution F (Y true)
since it contains the variable Y
which is not in scope of the metavariable
when checking that the expression refl has type X ≡ F (Y true)
-} Here the problem is that the occurs check currently only looks at the type of the variable |
I've been slowly getting convinced that in order to deal correctly with eta-equality for the unit type, the occurs checker needs to become type-aware. Below is the example that convinced me that a purely syntactic check will never be fully satisfactory. open import Agda.Builtin.Unit
open import Agda.Builtin.Equality
data D (A : Set) : Set₁ where
c : ((Set → A) → A) → D A
mutual
x : D ⊤
x = _
solve : {Y : Set} → x ≡ c (λ G → G Y)
solve = refl
{-
Cannot instantiate the metavariable _8 to solution c (λ G → G Y)
since it contains the variable Y
which is not in scope of the metavariable
when checking that the expression refl has type x ≡ c (λ G → G Y)
-} Note that in the internal representation of the solution term I guess this means that we should make the occurs check type-directed. However, I am a bit scared of the potential negative impact on performance this could have. Perhaps we should instead have a way of caching the current type and context computed by the main typechecker for each term in internal syntax, so we can avoid having to recompute them each time they are needed. OTOH the memory cost of that might actually be worse. |
Possible duplicate/sister issue: #2625 |
Slowly making progress on this at https://github.com/jespercockx/agda/tree/issue5837 |
I now have a version that is mostly working (it checks all of Succeed and Fail as well as the standard library), however I am stuck on a very mysterious error in the cubical library:
I tried inserting additional calls to |
I'm not in a situation where I can easily compile Agda today, but I believe this is my fault. Check out the normal form of λ i →
transp {λ _ → ℓ-max ℓ ℓ'}
(λ _ →
PathP {ℓ-max ℓ ℓ'} (λ i₁ → P (merid (f a) i₁) .fst) (F north)
-- ^^^^^^^^^^ woops!
(F south))
i (λ i₁ → F (merid a i₁)) If you change these lines to read comp (lam "i" $ \i -> l <@> i <@> j) (lam "i" $ \ i -> bA <@> i <@> j) (phi `imax` (ineg j `imax` j))
(lam "i'" $ \i -> combineSys (l <@> i <@> j) (bA <@> i <@> j) does the issue disappear? If not, I'll be back home tomorrow, where I can have a better look. This code is definitely wrong; but I'm not sure whether it's the cause of what you're seeing or not. |
Well it definitely makes a difference:
This points to the |
Yeah, that one's still on me — just more recently 😅 PathP does not take a line of levels, and diff --git a/src/full/Agda/TypeChecking/Primitive/Cubical.hs b/src/full/Agda/TypeChecking/Primitive/Cubical.hs
index 589a2a70c7..4cdfc8be8e 100644
--- a/src/full/Agda/TypeChecking/Primitive/Cubical.hs
+++ b/src/full/Agda/TypeChecking/Primitive/Cubical.hs
@@ -358,12 +358,12 @@ doPathPKanOp (TranspOp phi u0) (IsFam l) (IsFam (bA,x,y)) = do
-- In reality to avoid a round-trip between primComp we use mkComp
-- here.
comp <- mkComp $ "transport for path types"
- [l, u0, phi] <- traverse (open . unArg) [l, u0, ignoreBlocking phi]
- [bA, x, y] <- mapM (\ a -> open . runNames [] $ lam "i" (const (pure $ unArg a))) [bA, x, y]
+ [u0, phi] <- traverse (open . unArg) [u0, ignoreBlocking phi]
+ [l, bA, x, y] <- mapM (\ a -> open . runNames [] $ lam "i" (const (pure $ unArg a))) [l, bA, x, y]
lam "j" $ \ j ->
- comp l (lam "i" $ \ i -> bA <@> i <@> j) (phi `imax` (ineg j `imax` j))
- (lam "i'" $ \i -> combineSys l (bA <@> i <@> j)
+ comp (lam "i" $ \i -> l <@> j) (lam "i" $ \ i -> bA <@> i <@> j) (phi `imax` (ineg j `imax` j))
+ (lam "i'" $ \i -> combineSys (l <@> j) (bA <@> i <@> j)
[ (phi, ilam "o" (\o -> u0 <@@> (x <@> pure iz, y <@> pure iz, j))) I poked around the modules you mentioned and I don't see anything suspicious in the normal forms anymore. With my previous suggestion, reducing the RHS of I think your branch https://github.com/jespercockx/agda/tree/issue5837 is out of date: even without the fix (either version!), neither |
Now I'm getting yet another one:
I'll also try to bring my branch up to date with latest master to see if that solves anything. |
I've rebased on current master (and pushed it to my branch) but I still get the same error from my last message. |
Thanks! I'll investigate. |
The bug fix breaks code and seems to have caused a massive performance regression. Furthermore the error is not that Agda accepts too much code, but that Agda rejects too much code. I'd like to use the development version of Agda, but because of this bug fix I'm mostly using Agda 2.6.3 at the moment. I suggest that the change is reverted. |
I agree that the current situation is not good. I will spend the last day at the Agda meeting tomorrow to see if I can find a fix to the performance regression, and otherwise I will roll back (part of) the change to fix the performance regressions until we find a better implementation. |
After working unsuccessfully on finishing my fix yesterday, we had a discussion over dinner and I conceded that my change should be rolled back for now. I will prepare a PR that rolls back the change without losing all of the work I did on refactoring and improving the old code. |
This reverts commit 61a7593.
Thanks. |
Bumping this to 2.6.5, sadly. |
I encountered this issue while working on a possible solution for #5703. Consider the following example:
Here we get a hard error, even though eta-expanding
F Y
tott
leads to a valid solution. The problem is that the occurs check currently only considers singleton types for variables, but not for general expressions containing variables such asF Y
.To solve this properly, it seems like we might have to make the occurs check typed, and at every position consider whether the type is actually a singleton type so we can eta-expand the term away. Or perhaps it would be sufficient to do it for
Def
s andMetaV
s, since these are the only ones where there's actually a chance that the type is a singleton type.The text was updated successfully, but these errors were encountered: