<div dir="ltr"><div><br class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><blockquote>
It is needed to represent and prove the statement<br>
                "if (f 0) terminates, then  Even (f 0)"     (I).<br></blockquote>
I don't think it's possible to formulate inside Agda what it means for a function with a {-# NON_TERMINATING #-} pragma to terminate. So I also don't think it's possible to represent the statement you want. If you want to reason in Agda about termination of functions, I'd recommend to use the Delay monad as Nils suggested.<br><br></div>-- Jesper<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 5, 2018 at 10:48 AM, Sergei Meshveliani <span dir="ltr"><<a href="mailto:mechvel@botik.ru" target="_blank">mechvel@botik.ru</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tue, 2018-01-23 at 15:21 +0100, Jesper Cockx wrote:<br>
<br>
JC: ------------------------------<wbr>------------------------------<wbr>-------<br>
<span class="">If you define a function with a {-# NON_TERMINATING #-} pragma then<br>
it's generally not possible to prove things about it because Agda will<br>
refuse to evaluate it. This is also the problem in your example: even<br>
though in this case evaluation is terminating, Agda will play it safe<br>
and block *all* evaluation of the NON_TERMINATING function. So I don't<br>
think what you're trying to do is currently possible in Agda.<br>
<br>
A workaround is to postulate the clauses of the non-terminating function<br>
as propositional equalities (i.e. elements of the ≡ type). This allows<br>
you to prove properties of the non-terminating function without breaking<br>
the Agda typechecker (as you risk doing when using TERMINATING). In your<br>
example:<br>
</span>[..]<br>
<span class=""><br>
postulate<br>
  find-yes : (m n : ℕ) ( pmn :   P m n) → p? m n ≡ yes pmn →<br>
                                          find m n ≡ (n , pmn)<br>
  find-no  : (m n : ℕ) (¬pmn : ¬ P m n) → p? m n ≡ no ¬pmn →<br>
                                          find m n ≡ find m (suc n)<br>
</span>[..]<br>
<span class=""><br>
Something we could consider adding to Agda is some facility to get hold<br>
of the clauses of a non-terminating function automatically, so you<br>
wouldn't have to postulate them.<br>
</span>------------------------------<wbr>------------------------------<wbr>-------------<br>
<br>
<br>
<br>
Thank you. This is interesting.<br>
<br>
My goal is to find a simple way to express in Agda proofs about an<br>
algorithm which termination domain is not known.<br>
Is there a simpler approach than applying coinductive types and `delay'<br>
monad?<br>
<br>
I try your approach of "postulate-clauses" on the following simple<br>
example.<br>
<br>
f (m : ℕ)  searches for  n ≥ m  such that  P n,  and when finds,<br>
returns  n + n.<br>
It is needed to represent and prove the statement<br>
                "if (f 0) terminates, then  Even (f 0)"     (I).<br>
<br>
------------------------------<wbr>------------------------------<wbr>--------<br>
open import Function         using (_∘_)<br>
open import Relation.Nullary using (Dec; yes; no; ¬_)<br>
open import Relation.Unary   using (Decidable)<br>
open import Relation.Binary.<wbr>PropositionalEquality as PE using<br>
                                  (_≡_; refl; sym; trans; cong; subst)<br>
open import Data.Product using (_×_; _,_; ∃)<br>
open import Data.Nat using (ℕ; suc; _+_; _<_; _>_; _≤_)<br>
open import Data.Nat.Properties using<br>
            (≤-refl; ≤-reflexive; ≤-trans; m+n∸m≡n; +-comm; +-assoc;<br>
             m≤m+n; <⇒≱; ≰⇒>; module ≤-Reasoning)<br>
<br>
postulate  P  : ℕ → Set<br>
<span class="">           p? : Decidable P<br>
<br>
{-# NON_TERMINATING #-}<br>
</span>f : ℕ → ℕ                -- find n satisfying (P n) and return  n + n<br>
f n<br>
    with p? n<br>
... | yes _ = n + n      -- found<br>
... | no  _ = f (suc n)  -- try next<br>
<br>
<br>
postulate  f-yes :  ∀ n → P n   → f n ≡ n + n<br>
           f-no  :  ∀ n → ¬ P n → f n ≡ f (suc n)<br>
<br>
data Even : ℕ → Set<br>
     where<br>
     even0  : Even 0<br>
     even+2 : {n : ℕ} → Even n → Even (suc (suc n))<br>
<br>
postulate<br>
  even-n+n : ∀ n → Even (n + n)    -- the proof skipped for brevity<br>
<br>
postulate<br>
  minimizeSolution :  ∀ m → P m → ∃ (\n → P n × f 0 ≡ f n)<br>
  --<br>
  -- Can be proved by moving from m to minimal i such that (P i),<br>
  -- and by applying  f-yes, f-no.<br>
<br>
theorem :  ∀ m → P m → Even (f 0)<br>
theorem m pm =<br>
  let<br>
    (n , pn , f0≡fn) = minimizeSolution m pm<br>
    fn≡n+n  = f-yes n pn<br>
    even-fn = subst Even (sym fn≡n+n) (even-n+n n)<br>
  in<br>
  subst Even (sym f0≡fn) even-fn<br>
------------------------------<wbr>------------------------------<wbr>------<br>
<br>
<br>
First, I think that  (Even (f 0))  cannot be proved. Right?<br>
<br>
Further, the condition  "if (f 0) terminates"  is replaced with<br>
"∀ m → P m".<br>
<br>
I have an impression that `theorem' represents (I), in a certain sense,<br>
and proves it.<br>
Am I missing something?<br>
<br>
In general:<br>
this approach works when the programmer is able to formulate the<br>
statement<br>
                    "(g x1 ... xn)  terminates"<br>
<br>
as some Agda predicate in  x1 ... xn.<br>
For example, this is possible for any semidecision procedure  g<br>
(?)<br>
I wonder: how generic is this approach.<br>
<br>
What people think?<br>
<br>
Thanks,<br>
<br>
------<br>
Sergei<br>
<br>
<br>
<br>
</blockquote></div><br></div>