[Agda] termination by contradiction

Ulf Norell ulf.norell at gmail.com
Mon Jul 7 18:11:44 CEST 2014


On Mon, Jul 7, 2014 at 2:36 PM, Sergei Meshveliani <mechvel at botik.ru> wrote:

>
> I have installed Agda of July 7, 2014
> (in which the checker loop is fixed), and tried this program version:
>
> ----------------------------------------------------------------
> {-# NO_TERMINATION_CHECK #-}
> findNatByContra :
>            (P : ℕ → Set) → (P? : Decidable P) → ¬ (∀ n → ¬ P n) → Σ ℕ P
> findNatByContra P P? _ =  findFrom 0
>   where
>   findFrom : ℕ → Σ ℕ P
>   findFrom n = case P? n of \ { (yes Pn) → (n , Pn)
>                               ; (no _)   → findFrom (suc n) }
>
> eq3 : ℕ → Set
> eq3 = _≡_ 3
>
> eq3? : Decidable eq3
> eq3? = _≟_ 3
>
> find3 :  ¬ (∀ n → 3 ≢ n) → Σ ℕ (_≡_ 3)
> find3 H =  findNatByContra eq3 eq3? H
>
> thm' : (H : ¬ (∀ n → 3 ≢ n)) → proj₁ (find3 H) ≡ 3
> thm' _ = refl
> -----------------------------------------------------------------
>
> Ulf wrote that there will be difficulties in proving the properties
> of the results of  findNatByContra
> (right?).
>
> find3  means finding the first n equal to 3.
> And the programmer pretends that he has not a proof for
> ``exists n equal to 3'' other than termination by contradiction.
>
> thm'  is an attempt for such a proof.
>
> 1) The type checker does not loop.
> 2) It reports that  refl  does not have the needed type.
>
> Is this because it does not try to normalize  (find3 H)  in the type of
> thm' ?
>
> I am trying to provide the feature ``classic termination proof'' with
> some possibilities in Agda.
>
> Suppose the pragma  {-# NORMALIZE_UP m #-}
> means to do only  m  loops (`steps' ?) of normalization when
> type-checking.
> In this case,  m = 4  will, probably, accept this  refl  as a proof.
>
> Will it?
>

First of all, I got overruled on the behaviour of NO_TERMINATION_CHECK.
I've implemented a new pragma NON_TERMINATING with the non-looping
behaviour.

The reason you get a type error in thm' is as you suspect because the type
checker does not reduce find3 H (or rather it does reduce find3, but not
findNatByContra).

Probably m = 4 would not be enough since each iteration of findFrom
requires several reductions. Fortunately you can program this yourself
without the need of a special pragma. Here's my version:

private
  {-# NON_TERMINATING #-}
  -- This won't be reduced by the type checker
  findFromUnsafe : {P : ℕ → Set} (P? : Decidable P) → ℕ → Σ ℕ P
  findFromUnsafe P? n =
    case P? n of
    λ { (yes Pn) → (n , Pn)
      ; (no _)   → findFromUnsafe P? (suc n) }

  -- This will be reduced
  findFromSafeish : {P : ℕ → Set} (P? : Decidable P) → ℕ → ℕ → Σ ℕ P
  findFromSafeish P? zero n = findFromUnsafe P? n
  findFromSafeish P? (suc steps) n =
    case P? n of
    λ { (yes Pn) → (n , Pn)
      ; (no _)   → findFromSafeish P? steps (suc n) }

findNatByContra :
         ℕ → (P : ℕ → Set) → (P? : Decidable P) → ¬ (∀ n → ¬ P n) → Σ ℕ P
findNatByContra steps P P? _ = findFromSafeish P? steps 0

eq3 : ℕ → Set
eq3 = _≡_ 3

eq3? : Decidable eq3
eq3? = _≟_ 3

find3 :  ¬ (∀ n → 3 ≢ n) → Σ ℕ (_≡_ 3)
find3 H =  findNatByContra 4 eq3 eq3? H

-- Checks
thm' : (H : ¬ (∀ n → 3 ≢ n)) → proj₁ (find3 H) ≡ 3
thm' _ = refl

The trick here is that for the first 'steps' iterations you run the safe
findFrom that does reduce, and
when you run out of steps you fall back to the unsafe one which doesn't.

/ Ulf
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.chalmers.se/pipermail/agda/attachments/20140707/d8a9fc4b/attachment.html


More information about the Agda mailing list