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
Strong normalization broken in an open context #1428
Comments
But this does not break normalization! Original comment by |
Is this a problem? unfoldauxNat' : (f : ∀ i → Nat i) → ∀ i → Set1
unfoldauxNat' f i = unfoldauxNat f i (f i)
problem : (f : ∀ i → Size< i) (g : ∀ i → Nat (f i)) → ∀ i → Set1
problem f g i = unfoldauxNat' (\ i → suc (f i) (g i)) i Original comment by |
open import Common.Size
open import Common.Prelude
data Wrap (A : Set) : Set where
wrap : A → Wrap A
module M (f : ∀ i → Wrap (Size< i)) where
test : ∀ i → Wrap (Size< i) → ⊥
test i (wrap j) = test j (f j)
module N (g : ∀ i → Size< i) where
open M (λ i → wrap (g i))
loop : Size → ⊥
loop i = test i (wrap (g i))
-- module N's code leaves size constraint (↑ g i) =< i : Size open, which should hold.
-- Thus, we almost loop. A culprit seems to be that Size : Set. It should live in its own universe. Original comment by
|
Here is a variant that actually uses an (empty) sized type D. open import Common.Size
open import Common.Prelude
data D (i : Size) : Set where
wrap : (j : Size< i) → D i
module M (f : ∀ i → D i) where
test : ∀ i → D i → ⊥
test i (wrap j) = test j (f j)
module N (g : ∀ i → Size< i) where
f : ∀ i → D i
f i = wrap (g i)
open M f
loop : Size → ⊥
loop i = test i (f i) Original comment by |
A bit more nicely, this test is written: open import Common.Size
open import Common.Prelude
-- Note: the assumption of pred is absurd,
-- but still should not make Agda loop.
module _ (pred : ∀ i → Size< i) where
data D (i : Size) : Set where
wrap : (j : Size< i) → D i
loop : ∀ i → D i → ⊥
loop i (wrap j) = loop j (wrap (pred j))
-- Loops during injectivity check
d : ∀ i → D i
d i = wrap (pred i)
absurd : ⊥
absurd = loop ∞ (d ∞) Original comment by
|
Here is a variant that uses a size in the recursive call that origins from a subtree. (Andrea's original example.) data D (i : Size) : Set where
c : (j : Size< i) → D j → D i
module _ (pred : ∀ i → Size< i) (d : ∀ i → D i) where
loop : ∀ i → D i → ⊥
loop i (c j _) = loop j (c (pred j) (d (pred j))) Original comment by |
I think I want to disallow functions into Size and Size< to prevent this exploit. Original comment by |
I introduce a new sort SizeUniv to single out types Size and Size< and to prevent forming function spaces between them (so no function spaces in SizeUniv). As a consequence, the SIZE builtins cannot have displayable Agda types any more: However, currently advance on this issue is stuck on the internal (hackish) I pushed my progress so far. Original comment by
|
Original comment by |
Fixed by e69bc91 TODO: proper implementation of PTS rules in the presence of sort metas. Original comment by
|
Currently, one can work around the "no-functions-into-size" check with parametrized modules. open import Common.Size
data ⊥ : Set where
module Pred (i : Size) where
postulate
pred : Size< i
open Pred
data D (i : Size) : Set where
c : Size< i → D i
iter : ∀ i → D i → ⊥
iter i (c j) = iter j (c (pred j))
loop : Size → ⊥
loop i = iter i (c (pred i)) Original comment by
|
Fixed by forbidding size postulates in parametrized modules: f2740b9 Original comment by
|
-- One can still make Agda loop by defining pred with a hole.
-- However, I think this should maybe not be forbidden,
-- as then abbreviation of sizes in where clauses become impossible.
open import Common.Size
data ⊥ : Set where
data D (i : Size) : Set where
c : Size< i → D i
module _ (i : Size) where
pred : Size< i
pred = ?
-- The injectivity test loops here.
iter : ∀ i → D i → ⊥
iter i (c j) = iter j (c (pred j))
absurd : ⊥
absurd = iter ∞ (c (pred ∞)) Original comment by |
As a result of fixing this we have more BUILTIN pragmas which also introduces the constants. For me, a pragma can be disregarded by some tools or alternative versions of Agda. I know that the situation between builtins, primitives, and internal constructs is not really clear yet. In particular while I understand that SizeUniv should be treated a bit like Set, Size, Size<, ↑_, and ∞ all have types and could then stay postulates. Original comment by |
Indeed, they could remain postulates, if this is desirable. Maybe there is another way to fix this issue, as the SizeUniv does not really harmonize with the universe hierarchy (at least the current implementation). One could restrict Size< to negative positions, as in (i : <Size j) -> ... Original comment by |
With SizeUniv, sorts are no longer linear order, and the ptsRule is no longer just maximum (lub). This could be implemented properly, but is serious effort due to the optimizations done for levels. This patch defines SizeUniv = Set, so all the code for SizeUniv should be dead. I keep it, because I might come back and implement the ptsRule properly.
We could try re-enabling |
Original issue reported on code.google.com by
sanzhi...@gmail.com
on 10 Feb 2015 at 7:24The text was updated successfully, but these errors were encountered: