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

Carlos Camarao carlos.camarao at gmail.com
Wed Jul 3 17:09:48 CEST 2013


>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).

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   = if ⌊ n1 ≟ n2 ⌋ then
mgu1 pairs_t v c k else nothing  -- line I

mgu1 ((Con n1 , Con n2) ∷ pairs_t)   v (suc c) k  with n1 ≟
n2                     -- line W1
mgu1 ((Con n1 , Con .n1) ∷ pairs_t)  v (suc c) k  | yes refl = mgu1
pairs_t  v c k -- line W2
mgu1 ((Con n1 , Con n2) ∷ pairs_t)   v (suc c) k  | no _     =
nothing             -- line W3

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

pairs_t' = applyL s pairs_t

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

else mgu1 pairs_t v c k
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/6a30fa80/attachment-0001.html


More information about the Agda mailing list