Skip to content
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

Termination checker still incompatible with univalence #5910

Open
andreasabel opened this issue May 16, 2022 · 10 comments
Open

Termination checker still incompatible with univalence #5910

andreasabel opened this issue May 16, 2022 · 10 comments
Labels
cubical Cubical Agda paraphernalia: Paths, Glue, partial elements, hcomp, transp false Proof of the empty type which checks without known-unsafe flags (e.g. without --type-in-type) safe Subset of Agda features which is expected to be consistent termination Issues relating to the termination checker type: bug Issues and pull requests about actual bugs without-K K-related restrictions to pattern matching, termination checking, indices, erasure
Milestone

Comments

@andreasabel
Copy link
Member

Reported by @Saizan. Lifted from:

{-# OPTIONS --without-K #-}

data Zero : Set where

data Id (X : Set) : Set where
  i : X  Id X

mutual
  data WOne : Set where wrap : Id FOne -> WOne
  FOne = Zero -> WOne

data _<->_ (X : Set) : Set -> Set₁ where
  Refl : X <-> X

postulate
  iso : WOne <-> FOne

mutual
  noo : (X : Set) -> (WOne <-> X) -> Id X -> Zero
  noo .WOne Refl (i (wrap f)) = noo FOne iso f

absurd : Zero
absurd = noo FOne iso (i \ ())
@andreasabel andreasabel added type: bug Issues and pull requests about actual bugs termination Issues relating to the termination checker without-K K-related restrictions to pattern matching, termination checking, indices, erasure labels May 16, 2022
@andreasabel andreasabel added this to the 2.6.4 milestone May 16, 2022
@jespercockx jespercockx modified the milestones: 2.6.4, Later Aug 26, 2022
@nad nad added the false Proof of the empty type which checks without known-unsafe flags (e.g. without --type-in-type) label Nov 24, 2022
@nad nad modified the milestones: later, 2.6.4 Nov 24, 2022
@nad
Copy link
Contributor

nad commented Nov 24, 2022

I don't know why this was not labelled with false. It is easy to flesh out the example into one that type-checks with --erased-cubical --safe.

@andreasabel
Copy link
Member Author

andreasabel commented Jun 21, 2023

NB: Since this reproducer does a match of Refl, it should not be portable to Cubical Agda. However, I don't know enough to state this with certainty.

@nad wrote:

I don't know why this was not labelled with false. It is easy to flesh out the example into one that type-checks with --erased-cubical --safe.

Could you please do this? Currently we cannot place the safe label here, being short of a reproducer.

@szumixie
Copy link
Contributor

Path can be converted to <->, so it still works in Cubical Agda:

{-# OPTIONS --safe --cubical #-}

open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Isomorphism

data Zero : Set where

data Id (X : Set) : Set where
  i : X  Id X

mutual
  data WOne : Set where wrap : Id FOne -> WOne
  FOne = Zero -> WOne

data _<->_ (X : Set) : Set -> Set₁ where
  Refl : X <-> X

isom : Iso WOne FOne
isom =
  iso
    (λ _ ())
    (λ f  wrap (i f))
    (λ _  funExt λ ())
    (λ { (wrap (i _))  cong (λ f  wrap (i f)) (funExt λ ()) })

eq : WOne <-> FOne
eq = subst (λ X  WOne <-> X) (isoToPath isom) Refl

noo : (X : Set) -> (WOne <-> X) -> Id X -> Zero
noo .WOne Refl (i (wrap f)) = noo FOne eq f

absurd : Zero
absurd = noo FOne eq (i \ ())

@andreasabel andreasabel added cubical Cubical Agda paraphernalia: Paths, Glue, partial elements, hcomp, transp safe Subset of Agda features which is expected to be consistent labels Jun 26, 2023
@andreasabel
Copy link
Member Author

Thanks, @szumixie !

@andreasabel andreasabel modified the milestones: later, 2.6.4 Jun 26, 2023
@anuyts
Copy link
Contributor

anuyts commented Jun 26, 2023

mutual
  noo : (X : Set) -> (WOne <-> X) -> Id X -> Zero
  noo .WOne Refl (i (wrap f)) = noo FOne iso f

The pattern Refl forces X to be WOne, which may cause transport of any arguments whose type mentions X. By univalence, transport may involve arbitrarily complex functions. Indeed, the recursive call noo FOne iso f really boils down to noo WOne Refl (iso* f) (where iso* is a quick notation for transport). In order to make sure that the induction is structural, we need to ensure that the transport commutes with the nesting of constructors that we're peeling off. For example, if iso*(f) = i (wrap g), i.e. f = isoinv*(i (wrap g)), then we know by definition of transport of parametrized inductive types that

f = isoinv* (i (wrap g)) = i (isoinv* (wrap g))

However, we cannot commute isoinv* with wrap. As such, the nesting i (wrap [hole]) does not commute with transport w.r.t. X, and therefore should not qualify as proof of structural induction.
I'm confused what to do with indices (transport along an index creates an hcomp transport constructor), but as far as parameters are concerned, I think this paradox might be solved by requiring i (wrap [hole]) to be well-typed for X a variable, i.e. before equating it to WOne (but maybe after generalizing it from another more concrete expression).

@anuyts
Copy link
Contributor

anuyts commented Jun 26, 2023

It seems for indices, the necessary checks are in place?

{-# OPTIONS --cubical-compatible #-}

data E1 : Set where

data E2 : Set where

data Indexed : Set  Set₁ where
  e2 : Indexed E2

data _<->_ (X : Set) : Set -> Set₁ where
  Refl : X <-> X

oops : (X : Set)  X <-> E1  Indexed X  Set
oops .E1 Refl i = {!!}

Pattern match on i:

I'm not sure if there should be a case for the constructor e2,
because I get stuck when trying to solve the following unification
problems (inferred index ≟ expected index):
  E2 ≟ E1
when checking that the expression ? has type Set

although if you ask me it should bind a transport pattern.

@anuyts
Copy link
Contributor

anuyts commented Jun 26, 2023

Intriguingly (to me at least), this already raises a termination error:

{-# OPTIONS --without-K #-}

data Zero : Set where

record Unit : Set where
  constructor tt

data Id (X : Set) : Set where
  i : X  Id X

data _<->_ (X : Set) : Set -> Set₁ where
  Refl : X <-> X

postulate
  iso : {X}  Id X <-> X

noo : (X Y : Set) -> (Id X <-> Y) -> Y -> Zero
noo X .(Id X) Refl (i x) = noo X X iso x

absurd : Zero
absurd = noo Unit Unit iso tt
Termination checking failed for the following functions:
  noo
Problematic calls:
  noo X X iso x

@andreasabel
Copy link
Member Author

andreasabel commented Jun 26, 2023

Intriguingly (to me at least), this already raises a termination error:

Likely because there is a workaround in place for #1023, but it was shown to be incomplete in the current issue.

@andreasabel
Copy link
Member Author

This isn't a problem with --type-based-termination.
Proposal: disallow --syntax-based-termination when --cubical and --safe are on. (Or at least warn.)

@jespercockx jespercockx added the release blocker Issues blocking the next Agda release label May 2, 2024
@nad
Copy link
Contributor

nad commented May 10, 2024

Proposal: disallow --syntax-based-termination when --cubical and --safe are on. (Or at least warn.)

The new type-based termination checker has not been released yet. I don't think we should "force" people to use it before it has seen considerable use.

@andreasabel andreasabel removed the release blocker Issues blocking the next Agda release label Jul 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cubical Cubical Agda paraphernalia: Paths, Glue, partial elements, hcomp, transp false Proof of the empty type which checks without known-unsafe flags (e.g. without --type-in-type) safe Subset of Agda features which is expected to be consistent termination Issues relating to the termination checker type: bug Issues and pull requests about actual bugs without-K K-related restrictions to pattern matching, termination checking, indices, erasure
Projects
None yet
Development

No branches or pull requests

5 participants