[Agda] proofs for (NON)TERMINATING

Jesper Cockx Jesper at sikanda.be
Tue Jan 23 15:21:16 CET 2018


If you define a function with a {-# NON_TERMINATING #-} pragma then it's
generally not possible to prove things about it because Agda will refuse to
evaluate it. This is also the problem in your example: even though in this
case evaluation is terminating, Agda will play it safe and block *all*
evaluation of the NON_TERMINATING function. So I don't think what you're
trying to do is currently possible in Agda.

A workaround is to postulate the clauses of the non-terminating function as
propositional equalities (i.e. elements of the ≡ type). This allows you to
prove properties of the non-terminating function without breaking the Agda
typechecker (as you risk doing when using TERMINATING). In your example:

--------------------------------------------------------------------
open import Relation.Nullary using (yes; no; ¬_)
open import Relation.Binary  using (Decidable)
open import Relation.Binary.PropositionalEquality using (_≡_; refl; cong;
inspect; [_])
open import Data.Empty   using (⊥-elim)
open import Data.Product using (_,_; proj₁; proj₂; ∃)
open import Data.Nat     using (ℕ; suc)

postulate  P  : ℕ → ℕ → Set
           p? : Decidable P

{-# NON_TERMINATING #-}
find : (m : ℕ) → ℕ → ∃ (\k → P m k)
find m n
       with p? m n
...    | yes pmn = (n , pmn)       -- found
...    | no _    = find m (suc n)  -- try next

postulate
  find-yes : (m n : ℕ) ( pmn :   P m n) → p? m n ≡ yes pmn → find m n ≡ (n
, pmn)
  find-no  : (m n : ℕ) (¬pmn : ¬ P m n) → p? m n ≡ no ¬pmn → find m n ≡
find m (suc n)

lemma :  ∀ m → P m 0 → proj₁ (find m 0) ≡ 0
lemma m pm0
    with p? m 0 | inspect (λ m → p? m 0) m
... | yes pm0'  | [ proof ] = cong proj₁ (find-yes m 0 pm0' proof)
... | no  ¬pm0  | _         = ⊥-elim (¬pm0 pm0)
--------------------------------------------------------------------

Something we could consider adding to Agda is some facility to get hold of
the clauses of a non-terminating function automatically, so you wouldn't
have to postulate them.

-- Jesper

On Tue, Jan 23, 2018 at 2:14 PM, Sergei Meshveliani <mechvel at botik.ru>
wrote:

> Can somebody, please, explain how to express/prove the following lemma?
>
> -------------------------------------------------------------------
> open import Relation.Nullary using (yes; no)
> open import Relation.Binary  using (Decidable)
> open import Relation.Binary.PropositionalEquality using (_≡_; refl)
> open import Data.Empty   using (⊥-elim)
> open import Data.Product using (_,_; proj₁; ∃)
> open import Data.Nat     using (ℕ; suc)
>
> postulate  P  : ℕ → ℕ → Set
>            p? : Decidable P
>
> {-# NON_TERMINATING #-}
> find : (m : ℕ) → ℕ → ∃ (\k → P m k)
> find m n
>        with p? m n
> ...    | yes pmn = (n , pmn)       -- found
> ...    | no _    = find m (suc n)  -- try next
>
> lemma :  ∀ m → P m 0 → proj₁ (find m 0) ≡ 0
> lemma m pm0
>         with p? m 0
> ...     | yes _   =  refl
> ...     | no ¬pm0 =  ⊥-elim (¬pm0 pm0)
> --------------------------------------------------------------------
>
> For some P above the algorithm `find' is not terminating.
> So that this program would not type-check without pragma.
> The TERMINATING pragma is wrong to set.
> So, NON_TERMINATING is needed (?).
>
> Then, it occurs that `lemma' is not type-checked.
> This contradicts to the fact that  (find m 0)  terminates when  (P m 0)
> is satisfied.
>
> Is it possible to express and prove in Agda the above lemma?
>
> Thanks,
>
> ------
> Sergei
>
> _______________________________________________
> Agda mailing list
> Agda at lists.chalmers.se
> https://lists.chalmers.se/mailman/listinfo/agda
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.chalmers.se/pipermail/agda/attachments/20180123/8813879b/attachment.html>


More information about the Agda mailing list