どつとパタン

昨日のアレはMLで質問してみました
http://thread.gmane.org/gmane.comp.lang.agda/1015

すると、Wouterさんが、
http://wiki.portal.chalmers.se/agda/agda.php?n=Docs.DatatypeAndFunctionDefinitions
ここにdot patternがあるからそれを使えば良いんじゃね!!という事を教えてくれました。

When pattern matching on an element of an inductive family we get information about the index.

To distinguish parts of a pattern which are determined by pattern matching (the inaccessible patterns)
and the parts which constitutes the actual pattern matching,
the inaccessible patterns are prefixed with a dot.

これはなんだか様子がおかしそうです。訳してみよう。

inductive familyの要素でのパターンマッチをする時に、インデクスについての情報を得る。(どういう事?)

2つのパターンを見分けられるようにしている。
1.パターンマッチにより決定されるパターン(the inaccessible patterns)と
2.実際のパターンマッチを構成するパート
である。

the inaccessible patternには、dot(.)がプレフィクスとして付けられる。

謎だなー。

実例として

even+ : (n m : Nat) → IsEven n → IsEven m → IsEven (n + m)
even+ .zero          m  evenZ        em = em
even+ .(suc (suc n)) m (evenSS n en) em = evenSS (n + m) (even+ n m en em)

というのがあって、2つ目のパターンで、nが(succ (succ n))と、(evenSS n en)の2箇所で出現している(repeated variableどうのこうのと普通は起こられる)とか謎がある。

The proof is by recursion on the proof that n is even.
Pattern matching on this proof will force the value of n
and hence the patterns for n are prefixed with a dot to indicate that they are not part of the pattern matching.

ふむ。

indicate that they are not part of the pattern matching.か・・・。

例えば

-- dot patternを使わない
even+ : (n m : Nat) → IsEven n → IsEven m → IsEven (n + m)
even+ zero m evenZ em = em
even+ (succ (succ n)) m (evenSS n en) em = evenSS (n + m) (even+ n m en em)

と、

Repeated variables in left hand side: n
when scope checking the left-hand side
even+ (succ (succ n)) m (evenSS n en) em in the definition of even+

とか言われちゃうワケですね。

かと言って

even+ : (n m : Nat) → IsEven n → IsEven m → IsEven (n + m)
even+ zero m evenZ em = em
even+ (succ (succ n)) m (evenSS n' en) em = evenSS (n + m) (even+ n m en em)

こう書けば、

n' != n of type Nat
when checking that the pattern evenSS n' en has type
IsEven (succ (succ n))

こう叱られてしまう。
これは、型シグネチャ的には当然なアレで(succ (succ n)) と IsEven (succ (succ n'))から n と n'のunifyになって、これは失敗してダメだと。

まずなんとかして型チェックをくぐり抜けないと行けないが、かといってRepeated variableには出来ない・・・として、dot patternの登場という感じなのかな。

で、「実行時」にはdotが付いている所とはパタンマッチは行わないと・・・。そんな感じなのかな。

手元で書いたのは

data Unit : Set0 where
  unit : Unit

data Bool : Set0 where
  true : Bool
  false : Bool

data Ty : Unit -> Set0 where
  ty : (u : Unit) -> Ty u

data Vh {A : Set0} : A -> Set0 where
  vh : (a : A) -> Vh a

postulate dummy1 : Ty unit

f : Ty unit -> Bool -> Ty unit
f (ty .unit) true = (ty unit)
f (ty .unit) false = dummy1
{-
f a _ = a これを書くと
Unreachable clause
when checking the definition of f
などと出る
-}

v1 = f (ty unit) true
v1' = vh v1
-- Vh (ty unit)

v2 = f dummy1 false
v2' = vh v2
-- Vh (f dummy1 false)

なんだろう・・・。

f a _ = aが書けないのが嫌だし・・・。

もう一度Coq

Inductive Unit : Set := unit : Unit | unit2 : Unit. (* 何故かunit2を付けないと、fで _ が書けない *)

Inductive Bool : Set := true : Bool | false : Bool.

Inductive Ty {A : Set} : A -> Set := ty (a : A) : Ty a.

Axiom nanka : Ty unit.

Definition f (arg : Ty unit) :=
  match arg with
    | ty unit => true
    | _ => false
  end.

Definition x1 := Eval compute in ty (f (ty unit)).
(* Check x1 -> x1 : Ty true *)

Definition x2 := Eval compute in ty (f nanka).
(*Check x2 ->
x2
     : Ty
         match
           nanka in (Ty u)
           return match u with
                  | unit => Bool
                  | unit2 => Bool
                  end
         with
         | ty a =>
             match
               a as a0
               return match a0 with
                      | unit => Bool
                      | unit2 => Bool
                      end
             with
             | unit => true
             | unit2 => false
             end
         end
*)

これじゃなくて

Inductive Unit : Set := unit : Unit.

Inductive Bool : Set := true : Bool | false : Bool.

Inductive Ty {A : Set} : A -> Set := ty (a : A) : Ty a.

Axiom nanka : Ty unit.

Definition f (arg : Ty unit) :=
  match arg with
    | ty unit => true
  end.

Definition x1 := Eval compute in ty (f (ty unit)).

Definition x2 := Eval compute in ty (f nanka).
(*
Check x2 ->
x2
     : Ty
         match nanka in (Ty u) return match u with
                                      | unit => Bool
                                      end with
         | ty a =>
             match a as a0 return match a0 with
                                  | unit => Bool
                                  end with
             | unit => true
             end
         end
*)

ううーん・・・。これなんで型チェック通るんだろう。

そもそも、型に対する値を必要とするパターンマッチ(match)で、値が無い謎の物体Xを持って来ても、パターンマッチのやりようが無い・・・のか・・・。とすると、後者は分かった。

でも、前者の例、何故unit2がパタンマッチに現れているんだろう。