[Agda] Termination checking, if-then-else X with

Carlos Camarao carlos.camarao at gmail.com
Wed Jul 3 18:07:42 CEST 2013


On Wed, Jul 3, 2013 at 12:09 PM, Carlos Camarao <carlos.camarao at gmail.com>wrote:

> >Unfortunately, the termination checker cannot deal well with tuples.
> Please try a curried version of mgu1 instead:
> >  mgu1 : List (T * T) -> N -> N -> N -> Maybe Subs
> >Cheers,
> >Andreas
>
> Thanks Andreas! Surprisingly (for me), changing to a curried version did
> work! (Surprising for me because I think making the termination checker
> work with tuples also should not be difficult).
>
> The curried version of mgu1 is below; it compiles ok also with a
> with-expression (i.e. it also compiles ok by uncommenting lines W1,W2,W3
> and commenting line I).  ...
>

Unfortunately, the problem "with-expression versus if-then-else" appears
again, in the following curried version of mgu1: the code below compiles ok
but mgu1 becomes colored in light salmon if if-then-else is replaced by a
with-expression (i.e. if lines I1 to I4 are commented and lines W1 to W5
are uncommented).

Cheers,

Carlos

=================================================================
module Unif where

open import Relation.Nullary.Decidable using (⌊_⌋)
open import Data.Bool                  using (Bool; false; _∨_;
if_then_else_)
open import Data.Nat                   using (ℕ; suc; _+_; _≟_; zero)
open import Data.Maybe.Core            using (Maybe; nothing; just)
open import Data.Product               using (_×_; _,_; proj₁)
open import Data.List                  using (List; []; [_]; _∷_; map; sum;
length; concat; filter)
open import Function                   using (_∘_)
open import Relation.Nullary.Core      using (yes; no)
open import Relation.Binary.Core       using (Decidable; _≡_; refl)

{- ===================== Ty.agda ===================================-}

𝕍ar  : Set
𝕍ar = ℕ

𝕍ars : Set
𝕍ars = List ℕ

mem : ℕ → 𝕍ars → Bool
mem _ []      = false
mem a (b ∷ x) = ⌊ a ≟ b ⌋ ∨ mem a x

union : 𝕍ars → 𝕍ars → 𝕍ars
union []      y = y
union (a ∷ x) y = if mem a y then union x y else a ∷ union x y

data 𝕋 : Set where
 Con : ℕ → 𝕋     {- type constructor -}
 Var : ℕ → 𝕋     {- type variable -}
 _⇒_ : 𝕋 → 𝕋 → 𝕋 {- function type -}

vars : 𝕋 → 𝕍ars
vars (Con _)   = []
vars (Var v)   = [ v ]
vars (ta ⇒ tb) = union (vars ta) (vars tb)

varsP : 𝕋 × 𝕋 → 𝕍ars
varsP (t , t') = union (vars t) (vars t')

numVarsL : List (𝕋 × 𝕋) → ℕ
numVarsL = length ∘ concat ∘ map varsP

numVars : 𝕋 → ℕ
numVars = length ∘ vars

numConstructors : 𝕋 → ℕ
numConstructors (Con _)   = 1
numConstructors (Var _)   = 0
numConstructors (ta ⇒ tb) = 1 + numConstructors ta + numConstructors tb

numConstructorsP : (𝕋 × 𝕋) → ℕ
numConstructorsP (t , t') = numConstructors t + numConstructors t'

numConstructorsLP : List (𝕋 × 𝕋) → ℕ
numConstructorsLP = sum ∘ map numConstructorsP

{- ===========end of Ty.agda ========================================== -}

{- ===========Subst.agda ========================================== -}
Mapping : Set
Mapping = 𝕍ar × 𝕋

Subs : Set
Subs = List Mapping

emptySubs : Subs
emptySubs = []

insert : 𝕍ar → 𝕋 → Subs → Subs
insert v st s = (v , st) ∷ s

find : 𝕍ar → Subs → Maybe 𝕋
find v s with filter (λ vt → ⌊ proj₁ vt ≟ v ⌋)  s
... | []          = nothing
... | (_ , t) ∷ _ = just t

apply : Subs → 𝕋 → 𝕋
apply s (Var v) with find v s
... | just t       = t
... | nothing      = Var v
apply s (Con c)    = Con c
apply s (ta ⇒ tb)  = (apply s ta) ⇒ (apply s tb)

applyP : Subs → (𝕋 × 𝕋) → (𝕋 × 𝕋)
applyP s (t , t') = (apply s t , apply s t')

applyL : Subs → List (𝕋 × 𝕋) → List (𝕋 × 𝕋)
applyL s l = map (applyP s) l

{- =============end of Subst.agda
=============================================== -}

num_pairs_tv : 𝕋 × 𝕋 → ℕ
num_pairs_tv (Var _ , _)         = 0
num_pairs_tv (_ , Var _)         = 1
num_pairs_tv (ta ⇒ tb , tc ⇒ td) = num_pairs_tv (ta , tc) + num_pairs_tv
(tb , td)
num_pairs_tv _                   = 0

num_pairs_tvL : List (𝕋 × 𝕋) → ℕ
num_pairs_tvL = sum ∘ map num_pairs_tv

occurs : 𝕍ar → 𝕋 → Bool
occurs ν (Var ν')  = ⌊ ν' ≟ ν ⌋
occurs _ (Con _)   = false
occurs ν (ta ⇒ tb) = (occurs ν ta) ∨ (occurs ν tb)

mgu1 : List (𝕋 × 𝕋) → ℕ → ℕ → ℕ → Maybe Subs
--   v = number of variables
--   c = number of constructors
--   k = sum of number of pairs (t,v) where v is (and t is not) a variable;
-- k is the decreasing measure in rec. calls where t1 is not and t2 is a
var, first arg = ((t1,t2) ∷ _).
mgu1 [] _ _ _
   = just emptySubs
mgu1 ((Con _ , _) ∷ _) _ 0 _                                           =
nothing -- impossible
mgu1 ((Con n1 , Con n2) ∷ pairs_t)   v (suc c) k  with n1 ≟ n2
mgu1 ((Con n1 , Con .n1) ∷ pairs_t)  v (suc c) k  | yes refl = mgu1
pairs_t  v c k
mgu1 ((Con n1 , Con n2) ∷ pairs_t)   v (suc c) k  | no _     =
nothing
mgu1 ((Con _ , _ ⇒ _) ∷ _)  _ _ _                                    =
nothing
mgu1 ((Con _ , Var _) ∷ pairs_t)     v  c 0                         =
nothing -- impossible
mgu1 ((Con c1 , Var v2) ∷ pairs_t)   v  c (suc k)               = mgu1
((Var v2 , Con c1) ∷ pairs_t) v c k

mgu1 ((_ ⇒ _ , _) ∷ pairs_t)         _  0 _                           =
nothing -- impossible
mgu1 ((_ ⇒ _ , Con _) ∷ _)           _  _ _                          =
nothing
mgu1 ((_ ⇒ _ , Var v2) ∷ pairs_t)    _ _ 0                         =
nothing -- impossible
mgu1 ((ta ⇒ tb , Var v2) ∷ pairs_t)  v c (suc k)                 = mgu1
((Var v2 , ta ⇒ tb) ∷ pairs_t) v c k
mgu1 ((_ ⇒ _ , _ ⇒ _) ∷ _)           _ (suc 0) _                   =
nothing -- impossible
mgu1 ((ta ⇒ tb , tc ⇒ td) ∷ pairs_t) v (suc (suc c)) k        = mgu1 ((ta ,
tc) ∷ (tb , td) ∷ pairs_t) v c k

mgu1 ((Var _ , _)   ∷ _ )            0 _ _                              =
nothing -- impossible
mgu1 ((Var v1 , Var v2) ∷ pairs_t)   (suc v) c k                = let
s        = insert v1 (Var v2) emptySubs        -- line I1

pairs_t' = applyL s pairs_t                          -- line I2

in if ⌊ v1 ≟ v2 ⌋ then mgu1 pairs_t (suc v) c k -- line I3

else mgu1 pairs_t v c k                             -- line I4
{-
mgu1 ((Var v1 , Var v2) ∷ pairs_t)   (suc v) c k with v1 ≟
v2                                                             -- line W1
mgu1 ((Var v1 , Var .v1) ∷ pairs_t)   (suc v) c k | yes refl = mgu1 pairs_t
(suc v) c k                          -- line W2
mgu1 ((Var v1 , Var v2) ∷ pairs_t)   (suc v) c k  | no _      = let
s        = insert v1 (Var v2) emptySubs -- line W3

pairs_t' = applyL s pairs_t                    -- line W4

in mgu1 pairs_t v c k                              -- line W5
-}
mgu1 ((Var v1 , t2) ∷ pairs_t)       (suc v) c k            = let s
= insert v1 t2 emptySubs

pairs_t' = applyL s pairs_t

c'         = numConstructorsLP pairs_t'

k'         = num_pairs_tvL pairs_t'

in if occurs v t2 then nothing

else mgu1 pairs_t' v c' k'

======================================================================
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.chalmers.se/pipermail/agda/attachments/20130703/df157b80/attachment.html


More information about the Agda mailing list