ラベル プログラム検証論 の投稿を表示しています。 すべての投稿を表示
ラベル プログラム検証論 の投稿を表示しています。 すべての投稿を表示

2009年8月8日土曜日

【検証論】5 ホーア論理の数学 (その7)


*** 5.2.4 相対完全性定理
**** 再度自分なりに「十分な記述能力を持つ」を確認する
- どうもしっくりこない。この最弱前条件と十分な記
述能力を持つということが。そこで、再度自分なり
に確認する。
- まず、最弱前条件と呼ばれる、状態の集合の定義。

pwpI(P,B) = {p|∀p'.(ExecI'(P,p,p') => I’,p' |= B}

- これはわかる。
- 次に、表明Aが状態集合Sを表現する、ということの定
義。

S = {p| I,p |= A}

であるとき、表明Aは状態集合Sを表現する、と言う。

- 注意点。Sを表現するAはたくさんある。あるAが表現
しているとして、Aと同値な表明はすべて表現してい
ると言える。
- 注意点。∀p.(I,p |= A' => I,p |= A)となるA'があ
るなら、次が成り立つ。

∀p.(I,p |= A' => p ∈ S}

違う言葉でいうと、前者をみたす状態の集合は、後
者を満たす状態の集合の部分集合である。
- さて、任意のプログラムPと表明Bについて、
pwpI'(P,B)を表現する表明が存在するとき、
PHL(PV,AV,I)は十分な記述能力を持つという。
- このこと自体はそんなに理解は難しくない。
- このことを形式的に書いてみよう。
∀P∀B∃A∀.(I,p |= A => p∈pwpI(P,B) )
- ところで、とある{A}P{B}について

PHL(PV,AV,I) |= {A}P{B}

が成立する、ということの定義は、

∀p∀p'.(I',p |= A => (ExecI'(P,p,p') => I',p' |= B))

であった。ここでI'は解釈Iのうち表明に関する部分。
以降、Iは解釈の対象の部分に文脈によって限るものとする。
- これは、十分な記述能力を持つことの定義に似てい
る。どのくらい似ているか調べてみる。
- 十分な記述能力をもつことの形式的記述を展開してみる、

∀P∀B∃A∀p.(I,p |= A => p∈pwpI(P,B) )



∀P∀B∃A∀p.(I,p |= A => p∈{p''|∀p'.(ExecI(P,p'',p') => I,p' |= B} )

である。さて、pが集合に属するということは、その
内包表記の条件を満たすのでこの後の部分は集合表
記を外すことができる。

∀P∀B∃A∀p.(I,p |= A => ∀p'.(ExecI(P,p,p') => I,p' |= B} )

前半はp'を含まないので、p'の限量子は前に出すこ
とができる。

∀P∀B∃A∀p∀p'.(I,p |= A=> (ExecI(P,p,p') => I,p' |= B} )

これは完全であることの言明とほぼ同値である。違う
のは、PとBを先に固定したときに、それに対応するA
が必ず存在するという情報が入っていることだ。

これが重要なポイントだ。


- では、ここでこまごまやってきたことはどういう価
値があるのか、まとめてみる。
- まず、新しく「状態集合を表現する言明」という概念
を導入した。それをつかって、伴意の後半を満たす
状態集合を最弱前条件として定義した。さらに、最
弱前条件を表現するAをホーア論理が持つとき(十分
な記述能力があるとき)、伴意するということは、

∀P∀B∃A∀p.(I,p |= A => p∈pwpI(P,B) )

と同値であることがわかった。
- これによって、完全性を示すということは、

伴意 => 形式的に証明可能

を示すということであったが、それをホーア論理が
十分な記述力を持つときは、

∀P∀B∃A∀p.(I,p |= A => p∈pwpI(P,B) )
=> 形式的に証明可能

を示せばよいということになることがわかった。
- だいたいわかった。だけど本に記載されている次の論
理式は理解できない。

I |= {A}P{B} <=> I |= A => pwp(P,B) (5.8)

- とりあえず、これは無視する。上のように自分なり
に理解した形で相対完全性定理の証明をこころみる。
(5.8)を理解しないと証明できないとわかったら、理
解を試みる。
**** 閑話休題
- 相対完全性定理の証明を読み、自分でも書きつつ考
える。
- おおすじは理解できた。
- しかし代入性や項書換えのところがスキルが足りなく
ておいつかない。
- これをちゃんとやるには、項書換えについてそこそ
こ訓練しないと駄目な気がする。形式的言語の取り
回しスキルが全般的に足りていない。
- 相対完全性定理をちゃんとやるのは将来の課題として
先に進む。


のろのろ。

2009年8月4日火曜日

【検証論】5 ホーア論理の数学 (その6)

最弱前条件がわからない理由がわかった。

- わかった。そもそも表明の強い弱いのちゃんとした
定義がこの本でなされていないのだ。だから弱いの
かどうかがわからないのだ。この文脈からすると、
弱いの定義は、

「A => Bのとき、BがAより弱いと言う」

ということだろう。

これならば、pwp(P,B)が最弱であることは自明。


次回は相対完全性定理。
こつこつ。

2009年8月3日月曜日

【検証論】5 ホーア論理の数学 (その6)


*** 5.2.3 記述能力の十分条件
- 語彙の記述能力を議論するために、最弱前条件とい
う概念を導入する。
- 定義だが、誤字があるので原文ままではない。
---

Pがプログラム、Bが表明であるとき、最弱前条件とは、
次のように定義される集合pwpI(P,B)のことである。

pwpI(P,B)={p|すべてのp'について、(ExecI(P,p,p') => I,p' |= B)}が成立する。}

---
- pwpI(P,B)は状態の集合だが、固定された解釈Iにお
いては、状態の集合は表明を制約する。なぜか? 考
えてみる。
- 解釈Iと表明Aがあるとする。すると、表明Aの解釈I
における意味は、どのような環境(=状態)で表明Aが
真となるか、である。
- よって、状態の集合は、それらにて、そしてそれら
のみで真となる表明の指定と同一視してよい。ただ
し、この表明は単一とは限らない。そこで、「制約
する」としてみた。

- さて、pwpI(P,B)に対応する表明が語彙で表現可能か
どうかは語彙次第である。
- 任意のプログラムPと表明BについてpwpI(P,B)を表現
する表明が存在するとき、PHL(PV,AV,I)は「十分な
記述能力を持つ」という。
- さて、

I |= {A}P{B}

は、

すべての状態p,p'について、
I,p |= A => ExecI(P,p,p') => I,p' |= B
が真である。

ということであった。これは、

すべての状態pについて、
I,p |= A =>
(すべての状態p'について、ExecI(P,p,p') => I,p' |= B)
が真である。

と変形できる。さらに最弱前条件の定義から、

すべての状態pについて、
I,p |= A => (pがpwpI(P,B)に属する)
が真である。

と書き換えられる。

よって、

(I |= {A}P{B})
<=>
(すべての状態pについて、
I,p |= A => (pがpwpI(P,B)に属する)
が真である。)

という同値が成立する。

- さて、これは十分な記述力を持つことを仮定しては
いなかった。十分な記述力を持たない場合は、

(すべての状態pについて、
I,p |= A => (pがpwpI(P,B)に属する)
が真である。)

におけるI,p |= Aについて、pがpwpI(P,B)に属してい
ても偽になることがあるケースがあるということ。

十分な記述力を持つということは、そういうケース
が存在しないということ。すなわち、

(すべての状態pについて、
I,p |= A <= (pがpwpI(P,B)に属する)
が真である。)

が真である、ということ。
- うーん。ここで何故pwpI(P,B)が最弱といえるのなの
かがわからない。それは次回確認しよう。


よろよろ。

2009年8月2日日曜日

【検証論】5 ホーア論理の数学 (その5)


*** 5.2.2 完全性
- 完全性:
正しいものは全て、証明可能。
- 完全性の定義をそのままホーア論理PHLに適用する。
- PHL(PV,AV,S)が解釈Iに対して完全であるとは、
I |= {A}P{B}であれば必ずPHL(PV,AV,S) |- {A}P{B}
となることをいう。
- あたりまえだが、これではゲーテルの不完全性定理の
対象となり、ホーア論理は完全では無い、というこ
とになる。
- その様子
- {True}skip{B}という表明付きプログラムについて
考える。
- これが正しいということ
- I |= {True}skip{B}ということは、

- 表明付きプログラムの意味論。
- I |= True。
- skipは状態を変えない、ということだけ。

の3つから、I |= B と同値である。
- これが証明可能であるということ
- 次に{True}skip{B}がPHL(PV,AV,S)で証明可能
であるとする。するとその証明は一般的に、証
明アウトラインにて次の形で書くことができる。

{True}{A1}...{An}skip{An}...{A2n-1}{B}

- これが形式的に証明できるということは、

- 表明付きプログラムの意味論
- skip文の実行関係の特徴付け
- 帰結規則の定義

という3つから、次の論理式が真であることと
同値である。

True => A1, ... ,Ai => Ai+1, ... ,A2n-1 => B

- ポイントは、これは表明に関する論理式なの
で、PHL(PV,AV,S)全体を使って証明するので
はなく、Sを非論理的公理とする一階述語論理
(T(S)と書く)で証明するということだ。
- すると、

PHL(PV,AV,S) |- {True}{A1}...{An}skip{An}...{A2n-1}{B}

は、

T(S) |- True => A1, ... ,Ai => Ai+1, ... ,A2n-1 => B

と同値であるということになる。

ここで、先頭のTrueはトートロジなので常に
真だから、さらには、

T(S) |- B

と同値であると言える。
- まとめると、PHL(PV,AV,S)の完全性の定義が先の
ようであるということは、

PHL(PV,AV,S) |= {True}skip{B}
ならば
PHL(PV,AV,S) |- {True}skip{B}

ということであり、これは上で調査したところ、

I |= B
ならば
T(S) |- B

と同値である。
これは、ホーア論理の先の完全性の定義が、一階
述語論理の完全性とリンクしていることを示して
いる(ゲーデルの不完全性定理を考えるにあたっ
て)。

- やはりポイントは、T(S)というか表明の完全性の話
題であるということ。
- では、PHL(PV,AV,S)全体ではなくPHL(PV,AV,I)に限っ
て考えたらどうか。
- そうしても完全性は無条件には成り立たない。この
点が健全性と違う。健全性はPHL(PV,AV,I)であれば
無条件に成立した。
- 無条件に成立しない様子
- AVが極端に貧弱な場合、完全にならない。その様
子を。
- 例えば、整数の加減算のプログラムにおいて、AVの
語彙として、add1/1とsub1/1の関数記号(関数)が
与えられているとする。
- すると、プログラム全体の前条件と後条件はこの
語彙で表現できたとしても、プログラムの内部の
中間表明がAVの語彙で表現できないことがある。
- 例えば、
x := x + y;
x := x - y;
とすると、xは結局xであるがこういことをadd1/1、
sub1/1だけでは表現できない。表明にはwhileがな
いからだ。なので、add/2やsub/2が必要になる。
- というわけで、表明の語彙が貧弱だと、完全性だな
んだかんだと言う前な感じで「形式的証明を原理的
に記述不能」という状態になる。
- では、貧弱じゃない語彙ってどういうものなの?と
いうのが次項の話題。

刻んでるなぁ。。。
しかし一日一文字以上進む限り、いつかは終わる。

こつこつ。

2009年8月1日土曜日

【検証論】5 ホーア論理の数学 (その4)


**** whileについて考える

- 形式的理論の構築に沿って、whileの理解を深めてみ
たい。
- まず、ホーア論理の言語の構成部品のひとつである
プログラムの文法を定める。それをプログラミング
言語Minと呼ぶ。Minの中でwhile構文が定義されてい
る。
- 定義はこのとおり。

文 ::= while ブール式 do 文 od.

文となるものはこの他にもあるが抜き出して書いた。

- 続いて推論規則の定義にwhileが表れる。

Rwh(while文の規則)
{C^A}P{A}
----------------------------
{A} while C do P od {¬C^A}

- 推論規則は形式的証明に使うものであり、第一義に
は意味は無い。このような形の変形が許されるとい
うことだけだ。もちろん、この形の変形を推論規則
に選んだことに、意味論を見越した意図や狙いはあ
るのだが、今は分離して進める。
- しかし、この規則、不思議な形をしているよなぁ。
- ここまでが統語論と証明論?。

- 続いて意味論。
- まずラベル付きプログラムを導入する。その文法を
定義する。その中にwhileが表れる。

<A> ::= ラベル ":" while ブール式 do <A> od ラベル ":".

ラベルは他の語彙と衝突せず相互に識別できて無限個
あるなら何でもよくて、ここではl0,l1,...とする。
- あるプログラムPの意味を考えるときは、そのままで
は駄目であり、それをラベル付きプログラムに変換
するという手順。
- プログラムの意味というのは、このラベルをカウン
タが移動していくにあたってどういう風に状態が変
わるの、ということで数学的に形式化される。
- なので、Min言語の意味論とは、Min言語の文のラベ
ル付きのものにおいて、ラベルと状態(あわせて状況)が
どのように遷移するかを定義することにあたる。そ
こで、whileはどうなっているかというと、次のよう。
- ラベル付きプログラム

l0 : while C do l1 : P l2 : od l3 :

を考える。状況をと表し、初期状況を<p,l0>と
する。IPpを、「環境pにおけるプログラムの語彙PVに
対する解釈」を表す記号とする。

するとこのラベル付きプログラムの意味論は次のよ
うになる。

- <p,l0> (初期状況)
- l0からの遷移。while構文が統制している。
- IPp[C]がTrueならば、<p,l1>に遷移する。
- IPp[C]がFalseならば、<p,l3>に遷移する。
- l1からの遷移。
- <p,l1>を初期状態といて、Pの実行に入る。
- Pの実行が終わると、状態の詳細はPの内容により
けりだがいずれにしてもなんらなかの状態にな
るのでそれをp'とする。すると状況は、<p',l2>
となる。
- l2からの遷移。
- 状態を維持したままカウンタをl0にする。l1か
らの流れでいうと、状況は<p',l0>となる。
- ふむ。これはnaiveな定義だな。
- 続いて、実行関係というものを導入する。
- 実行関係とは何か。
- ここで採用している意味論においては、プログラム
の結果というのは、もしくはプログラムの実行の結
果または効果というは状態の変化しか無い。実行に
おいては、プログラムカウンタが構文に従って動き
回るということがおこるが、それは過程であって、
結果には結びつかない。(もちろんリアルな言語で副
作用がある場合は、そのプログラムカウンタの移動
に付随して別の結果をもたらすこともある)
- なので、プログラムPによって状態pが状態p'になっ
た、ということは、プログラムカウンタの動きの子
細を省きつつ、このプログラムの意味(論)を捉えて
いる。そこでこれを、

Exec(P,p,p')

と書き、実行関係と呼ぶ。これを実行関係というのは、
このExecを述語と捉えれば、Exec(P,a,b)がTrueなら
ば、aとbはPの実行関係であり、FalseならaとbはPの
実行関係ではない、などと運用できるからだ。

- では、Min言語の基本的な構文達の実行関係とはどの
ようなものかという興味がわく。すなわちプログラ
ムPにたいしてExec(P,a,b)がTrueとなるaとbの関係
というのは論理式であらわすとどうなるかというこ
とだ。
- ここでwhileの実行関係の特徴付け、がでてくる。
それが、

---
次のものを満すような、m(>=1)と、状態の列
p1,...,pmが存在する

(p=p1)^(p'=pm)^(I,pm /|= C) ^
(すべてのi(<m)について次のことが成り立つ ((I,pi |= C ^ ExecI(P,pi,pi+1))))
---

これ。
- これ、よく見ると、さっきwhileのラベル付きプログ
ラムの意味(論)でプログラムの実行を遷移で追いま
したが、それを論理式で書いただけですね。

- 閑話休題。

*** 5.2.1 健全性 (つづき)
- さて、while文がわかったので、つづき。

任意の状態p,p'について、

I,p |= A => Exec[I'](while C do P od,p,p') => I,p' |= {¬C ^ A}

が真である

ということが示すべきことであり、数学的帰納法を
やっているので、

I |= {C^A}P{A}

は真としてよいということであった。

- 整理すると、前提として、

I |= {C^A}P{A}
I,p |= A
Exec[I'](while C do P od,p,p')

が成立するときに、

I,p' |= {¬C ^ A}

が成立することを示せばよいことになる。

- Execの詳細に着目しよう。

次のものを満すような、m(>=1)と、状態の列
p1,...,pmが存在する

(p=p1)^(p'=pm)^(I,pm /|= C) ^
(すべてのi(<m)について次のことが成り立つ ((I,pi |= C ^ ExecI(P,pi,pi+1))))

であり、p=p1とp'=pmは覚えておくことにすると、

(I,pm /|= C) ^
(すべてのi(<m)について次のことが成り立つ ((I,pi |= C ^ ExecI(P,pi,pi+1))))

となる。

(I,pm /|= C)

の部分は、pm=p'だから、成立することを証明したい、

I,p' |= {¬C ^ A}

の¬Cのところそのままだ。だからこの部分は示せた。
なので、あとは、

I,pm |= A.

を示せばよい。さて、p1(=p),...,pm(=p')という状
態の列の関係は、

(すべてのi(<m)について次のことが成り立つ ((I,pi |= C ^ ExecI(P,pi,pi+1))))

であり、

I |= {C^A}P{A}

を表明付きプログラムの意味論で解釈すると、

I,p |= A

である。もちろんここのpはp1である。
前提に再度たちかえって、

I |= {C^A}P{A}

ということは、任意の状態pa,pbについて、

I,pa |= C^A => pa,pbがPの実行関係 => I,pb |= A

ということであったから、

I,p |= A
(すべてのi(<m)について次のことが成り立つ ((I,pi |= C ^ ExecI(P,pi,pi+1))))

の2つをiについて展開すると、

- i = 1
(I,p1 |= A) ^ (I,p1 |= C ^ ExecI(P,p1,p2))
(I,p1 |= A^C) ^ (ExecI(P,p1,p2)) ; 同値変形
であり、これはI |= {C^A}P{A}の{C^A}Pそのもの
なので、
(I,p2 |= A)
であることが成立している。
- i = 2
(I,p2 |= A) ^ (I,p2 |= C ^ ExecI(P,p2,p3))
...
(I,p3 |= A)
であることが成立している。
- ...
- i = m - 1
...
(I,pm |= A)
であることが成立している。

となる。正式な証明としてはiに関する数学的帰納法
を使う。

というわけで、

(I,pm |= A)

が成立していることが示せた。

- この証明によって、次のことが言えた。

「PHL(PV,AV,S)の形式的証明について、n>1として
n-1番目の行までが健全であるならば、n番目の行が
while文であるとき、n番目の行も健全である。」

- whileについてやったのと同様の方法にて、帰結規
則以外の推論規則についてもこのことを示すことが
できる。(割愛)

- ポイントは、これら帰結規則以外の証明においては、
「Sの任意の表明Aに対してI |= Aとなる」という本
体証明の前件を一切使っていないこと。なんのこっ
ちゃない、それが必要になるのは帰結規則だけであ
り、その他の推論規則についてはそれが無くともも
ともと健全だったということだ。

- では、帰結規則がn番目の行だったらどうなのか。

- まず帰結規則を再掲する。

PHL(PV,AV,S)の帰結規則は、

{B}P{C}
-------
{A}P{D}

ただし、

PHL(PV,AV,S) |- (A => B)
PHL(PV,AV,S) |- (C => D)

である

- 示すべきは、これが(n行目までが)形式的に証明でき
ており、n-1 行目まではくわえて健全性まで持って
いるときに、このn行目も健全と言えるかどうか、
だ。

- さて、付帯条件、

PHL(PV,AV,S) |- (A => B)
PHL(PV,AV,S) |- (C => D)

がn-1行目に属していると考えれば(こう考えていい
かどうかはもやもやしている)、これは、健全でも
あるので、

I |= (A => B)
I |= (C => D)

となる。

- すると、

I |= {B}P{C}

これを、表明付きプログラムの意味論で読み替える
て、

任意のp,p'について

I,p |= B => Exec(P,p,p') => I,p' |= C

が成立する

ということと、先の伴意をつなげば、

I,p |= A => I,p |= B => Exec(P,p,p') => I,p' |= C => I,p' |= D

となり、これは、

{A}P{D}

の意味論に他ならない。

- あれ、

「Sの任意の表明Aに対してI |= Aとなる」

をまた使ってないじゃん。。。

- やはり、

---
付帯条件、

PHL(PV,AV,S) |- (A => B)
PHL(PV,AV,S) |- (C => D)

がn-1行目に属していると考えれば
---

がまずいのだろう。

- 考える。。。

- まずくないかも。P89に

(S |- A => B) {B}P{C} (S |- C => D)
-----------------------------------
{A}P{D}

というのもあるから。

- 考える。。。

- これはやはりまずいのだろう。形式的な証明だけを
考えているときはまずくないのだが、健全性を考え
るときには、{B}P{C}がある行にいたる行の健全性か
ら、この行の健全性を証明するわけだが、その段階
では(S |- A => B) (S |- C => D)の健全性を示す
ことは不要だからだ。
- すると、

PHL(PV,AV,S) |- (A => B)
PHL(PV,AV,S) |- (C => D)

というときに、

I |= (A => B)
I |= (C => D)

が、

「Sの任意の表明Aに対してI |= Aとなる」

から言えるかどうか。。。

- ああ、言えるな。

- PVとAVはあくまで一階述語論理の範囲であるから、
一階述語論理は非論理的公理が健全ならば健全なの
で、それがそのまま適用されるということだ。

- これでホーア論理PHLの健全性については掴めた。

- なお、

「Sの任意の表明Aに対してI |= Aとなる」

は、PHL(PV,AV,I)についてはその定義から自動的に
満たされるので、

「PHL(PV,AV,I)は、解釈Iに対して健全である」

が成立する。


こつこつ。

2009年7月29日水曜日

【検証論】5 ホーア論理の数学 (その3)


*** 5.2.1 健全性
- 定義なので原文ママ引用。

---

ホーア論理の健全性 (soundness)

PHL(PV,AV,S)が、解釈Iに対して健全であるとは、
PHL(PV,AV,S) |- {A}P{B}であるときには、必ず
I |= {A}P{B} となることをいう。

---

- これはあくまで健全性とはどういうことかという定
義。ホーア論理が健全性をもっているかどうかをこ
れから調べる。

- さて、それにあたって次の補題をまず示すのがよい
ようだ。

---

PHL(PV,AV,S)が解釈Iに対して健全である必要十分条件
は、Sの任意の表明Aに対して I |= A となることである。

---

- えっと、「必要十分条件」って何だっけ?
- 岩波数学入門辞典によると、P => Q, Q => P のとき、
PはQの、QはPの必要十分条件というようだ。
- なので、この補題が成立することを確認するには、

「PHL(PV,AV,S)が解釈Iに対して健全である」
=>
「Sの任意の表明Aに対して I |= A となる」



「Sの任意の表明Aに対して I |= A となる」
=>
「PHL(PV,AV,S)が解釈Iに対して健全である」

を調べればよいようだ。

- 本に載っているこの証明がなんだかよく分からない。
そこで自分なりに考えてみる。

- まず第一の方向。

「PHL(PV,AV,S)が解釈Iに対して健全である」
=>
「Sの任意の表明Aに対して I |= A となる」

これを示せばよい。

- まず、

「PHL(PV,AV,S)が解釈Iに対して健全である」

ということは健全性の定義により、

「PHL(PV,AV,S) |- {A}P{B}であるときには、必ずI |= {A}P{B} となる」

ということであった。

- なので、この後半の I |= {A}P{B} をうまくとると、

「Sの任意の表明Aに対して I |= A となる」

が言えるのではないかな。

- さて、ここではAはSに属しているので、表明単体と
してみると公理として正しさは確保できている。
- すると推論規則の方の公理でスキップ文の公理があ
るので、

PHL(PV,AV,S) |- {A}skip{A}

は成り立つ。

- ところで、帰結規則をここで使うと

{A}skip{A}
---------------------
{<恒真論理式>}skip{A}

と推論できる。というのは、<恒真論理式> => A は、
AがSに含まれていることからTrue => Trueであり、ト
リビアルに成立するからだ

ここで、<恒真論理式>をTrueと書くことにすると、
健全性から、

I |= {True}skip{A}

が成り立つということになる。

- では、

I |= {True}skip{A}

が成り立つということはどういうことであろうか。

- これは、表明付きプログラムの意味論から、
全ての状態pおよび全ての状態p'について、

I,p |= True => Exec[I'](skip,p,p') => I,p' |= A

が成立するということ。

- さて、

Exec[I'](skip,p,p') <=> 'p = p

なので、これは、

I,p |= True => p = p' => I,p' |= A

が全てのpとp'で成立する、ということ。

- さて、Trueは恒真論理式なので、解釈によらず常に
正しいから最左は成立し、結果、任意のp'について、

I,p' |= A

となる。これは

I |= A

の正式表記であった。■

- さて、次は逆の条件、

「Sの任意の表明Aに対して I |= A となる」
=>
「PHL(PV,AV,S)が解釈Iに対して健全である」

を確認しよう。

- ここでも健全性の定義を使って詳細化すると、

「Sの任意の表明Aに対して I |= A となる」
=>
「PHL(PV,AV,S) |- {A}P{B}であるときには、必ずI |= {A}P{B} となる」

ということだ。

- あれ? これ、よく考えるとおかしくないか?

「Sの任意の表明Aに対して I |= A となる」

解釈Iは、表明付きプログラムに対する解釈だから、
表明付きプログラムではない単なる表明であるAが伴
意されることはないのでは?

たぶん、気持的には解釈Iの中の表明に関する部分に
よって、Aが伴意される、ということじゃないか。

ということで、その気持で行こう。

- さて、これは任意のPについて成立することを示さな
ければいけないからPはいろいろあるので大変である。
そこでPの行数に関する帰納法で確認することにしよ
う。

- ではまず、Pが1行のみのプログラムの場合はどうか。

- 「形式的証明」で一行のみで成立するプログラムとい
うのは、公理だけである。よって、代入文の公理と
スキップ文の公理を確認すればよい。
- 代入文の公理は、

{A[t/x]} x := t {A}

である。これが形式的に証明されているときに、

I |= {A[t/x]} x := t {A}

と言えるかどうか、だが、形式的に証明されている、
ということはこれが公理であることと同義なので、
そのこと自体はここでの確認において無価値かな。

- そこで、伴意の文を詳細化してみると、
任意の状態pとp'について、

I,p |= {A[t/x]} => Exec[I'](x := t,p,p') => I,p' |= {A}

が成立することを示せばよいことになる。

- ここで、

Exec[I'](x := t,p,p') <=> p' = p[Ip[t]/x]

なので、

任意の状態pとp'について、

I,p |= {A[t/x]} => p' = p[Ip[t]/x] => I,p' |= {A}

が成立する、

となる。この言明が真かどうか確認してみよう。

- まず、I,p |= {A[t/x]}が真でなければ、それ以降は
何であっても全体は真になる。なので、I,p |=
{A[t/x]}が真であるような状態pについて考えればよ
い。p' = p[Ip[t]/x]は、ちょっと奇妙だがp'を設定
しているだけなので、常に真と考える。すると、そ
んなp'において、I,p' |= {A} が成立すればOKとな
る。

- pは状態であり、これは環境と同義であった。
ということは、p[Ip[t]/x]は、pという環境において、
変数xについてはもともとpで割り付けていた値では
なく、Ip[t]を割り付ける、ということだ。

- これは項の代入性そのものであり、自明だろう。

- 次。スキップ文の公理

- スキップ文の公理は、

{A} skip {A}

である。これが形式的に証明されているときに、

I |= {A} skip {A}

と言えるかどうか、だが、形式的に証明されている、
ということはこれが公理であることと同義なので、
そのこと自体はここでの確認において無価値であろ
う。

- そこで、伴意の文を詳細化してみると、
任意の状態pとp'について、

I,p |= {A} => Exec[I'](skip,p,p') => I,p' |= {A}

が成立することを示せばよいことになる。

- ここで、

Exec[I'](skip,p,p') <=> p' = p

なので、

任意の状態pとp'について、

I,p |= {A} p' = p => I,p' |= {A}

が成立する、

となる。これは{A}が伴意されるなら{A}は伴意され
る、という言明なので、自明だろう。

- ゆえに、一行のみの形式的証明について成立するこ
とが確認できた。

- 次に、n>1として、n行から構成される形式的証明を
考えよう。数学的帰納法を用いるので、n-1行までは
正しい(伴意する)ことが確認できているとする。

- n行目が、公理(代入文 or スキップ文)であれば、一
行のみと同様に自明である。なので、n行目が推論規
則である場合を確認すればよい。すると、次のもの
について確認することになる。
- while文
- if文
- begin文
- 帰結規則

- まずwhile文からやろう。

- 今、n行の形式的証明があり、n-1行目までは健全で
あるとする。そして、n行目が、

{A} while C do P od {¬C ^ A}

であるとする。
- n行目がこうであるということは、n-1行目までのど
こかに、

{C^A}P{A}

がある、ということである。これは健全であるから、

I |= {C^A}P{A}

が成立しているということになる。これを情報とし
て、示すべきは、

I |= {A} while C do P od {¬C ^ A}

である。この伴意を詳細化すると、

任意の状態p,p'について、

I,p |= A => Exec[I'](while C do P od,p,p') => I,p' |= {¬C ^ A}

が真である

ということだ。

- さて、上記のwhile文のExecは次のものと同値である。

次のものを満すような、m(>=1)と、状態の列
p1,...,pmが存在する

(p=p1)^(p'=pm)^(I,pm /|= C) ^
(すべてのi(<m)について次のことが成り立つ ((I,pi |= C ^ ExecI(P,pi,pi+1))))

- どわーーー。while文がやっぱりわからん。

- ということで、とりあえずここまでとして、次回は、
while文について自分なりに整理しなおすことにする。


こつこつ。

2009年7月28日火曜日

【検証論】5 ホーア論理の数学 (その2)


** 5.2 ホーア論理の健全性と完全性
自分なりの言葉で書く。

- まず、ホーア論理の「形式的理論と意味論を定義で
きたので」とあるのですが、いろいろ定義してきた
が、この2つのものの境目がどこだっけ?と考えると、
思い出せない。。。歳を取るとは恐しいことだ。し
かしめげずに整理しなおすことにする。ホーア論理
の形式的理論と意味論の境目を明確にしよう。

- 形式的理論の定義:形式的理論とは形式化された理
論のことであり、次の2つから成る。
- 形式的理論の言語
- 語彙
- 変数
- 定数
- 関数記号
- 述語記号
- 項の定義
- 語彙をどのように組み合わせて項を成すかのルー
ル。
- 論理式の定義
- 論理記号の定義
- 項と論理記号をどのように組み合わせて論理式
を成すかのルール。
- 証明の形式化
- 後述。

- ふむ。形式的理論というのは統語論+証明と考えてい
いのかも。

- 形式的理論の意味論:形式的理論の意味論とは、形
式的理論の解釈である。解釈とは次のものどもであ
る。
- 語彙の解釈
数学の何かに対応させる。対応させかたは次のと
おり。
- 領域Dをきめる。
- Dの要素を定数に割り当てる。
- 関数記号に、D上の関数を割り当てる。
- {Truth,False}という真理値集合を導入する。
- D上の述語はD上の要素達から真理値集合への関
数であるとして定義する。
- 述語記号に、D上の述語を割り当てる。
- 項の解釈
- まず、変数の解釈のために、環境というものを
導入する。環境は、変数記号から定数記号(よっ
てDの要素)への関数である。
- 項(t)の解釈(Ip[t]) (再帰的定義)
- tが定数のとき、I[t]。すなわち語彙の解釈ど
おり。
- tが変数のとき、p(t)。すなわち環境(関数) ど
おり。
- tがまずは関数記号のとき、
I[f](Ip[t1],...Ip[tn])
というように、関数記号は語彙の解釈として、
引数については再帰的に解釈する。
- 論理式の解釈
論理式の解釈とは、それぞれの論理式に真偽値を
どう割り当てるかということである。
- まず、論理記号に対応する真理値関数を定義す
る。真理値関数はD上の関数ではなく、真理値集
合上の関数である。
- 論理積/2
- 論理和/2
- 含意/2
- 否定/1
- ただし、限量子については、真理値の集合(真理
値集合だけではない)から真理値の関数となる。
- 限量子(すべての)
- 限量子(ある)
- 続いて論理式の解釈を定める。
- 論理式の解釈は、項の解釈を前提として、論
理記号に論理関数を割り当てる形で再帰的に
真理値を計算するものとする。

- 形式的理論の証明
- 形式的理論の証明は次の2つを基礎とする。
- 公理と呼ぶ論理式(の指定)
- 公理は、論理的公理と非論理的公理に大別さ
れる。
- 推論規則(の指定)
- 形式的証明:形式的証明は、証明の記法を明確に
定めたものである。例えばヒルベルト型の形式的
証明などがある。(説明は割愛)

- なんかこれ、3回はブログに書いた気がする。。。

- めげずに形式的なホーア論理って何だったけ?をも
う一度やってみよう。

- とあるホーア論理構築 (なるべく簡潔に)
- 統語論
- プログラムの語彙(PV)を決める。
- PVの項の構文を決める。
- プログラムの構文をPVの項を基礎に決める。
- 表明の語彙(AV)を決める。(PVの拡張とする。)
- 表明の項の構文を決める。
- 表明の論理式の構文を、項を基礎に決める。
- 表明付きプログラムの構文を決める。

- 解釈
- PVの解釈を決める。
- 表明の論理式の解釈(Iとする)を決める。(これと
PVとの間にはいろいろ決めるが割愛。)

- 公理
- 論理的公理を決める。
- 非論理的公理は、解釈Iにて正しい論理式全てと
する。

- 推論規則
- 表明の推論規則を決める。
- 表明付きプログラムの推論規則を決める。

- 意味論
- ここまでで意味論が定義されているのは次のとお
り。
- PV
- AV
- 表明の項
- 表明の論理式
- ここまでで意味論が定義されていないのは次のと
おり。
- プログラム
- 表明付きプログラム
- プログラムの意味論を定義する。
- プログラムカウンタ
- 状況
- 状況の遷移。遷移関係
- 状態
- 状態の列
- 実行
- 実行関係
- 表明付きプログラムの意味論を定義する。
- {A}P{B}について、表明の部分は表明の意味論
として、Pの部分は実行関係を意味として、意
味論を決定。

- ふむ。一応、本を見なくても自分で組み立てられる
ようにはなった。


こつこつ。

2009年7月26日日曜日

【検証論】5 ホーア論理の数学


* 5 ホーア論理の数学
自分なりのポイントを、自分なりの言葉で書く。
- ホーア論理は4章で定義したような、形式的理論であ
る。
- 4章で定義したのは、主に統語論(Syntax)である。
- ただし、一階述語論理のフレームワークを採用して
いる部分や、解釈に因っている部分もあるので、一
部、意味論(Semantics)に入っている。
- 形式的理論なので、理論の健全性や完全性という概
念がある。
- 復習としてここで形式的理論の健全性と完全性を振
り返ると、、、
- 論理式Aは解釈Iと環境pに対して正しい、ということ
を、

I,p |= A

と書く。

- 論理式Aは解釈Iと任意の環境に対して正しい(伴意)
ということを、

I |= A

と書く。

- トートロジー。任意の解釈Iに対して I |= A が成立
するとき、Aをトートロジーと呼ぶ。

- 形式的に証明可能
- 形式的理論Tにおいて、形式的証明によって論理式
を証明できたとき、

T |- その論理式

と書く。

- 形式的理論Tが解釈Iにおいて完全性と持つというこ
とは、

任意の論理式Fに対して、I |= F ならば、T |- F と
なる

ということである。すなわち意味論としての正しさ
があるものは、統語論としての正しさも証明できる
ということ。

- 形式的理論Tが解釈Iに対して健全であるとは、

任意の論理式Fに対して、T |- F ならば、I |= F
となる

ということである。すなわち統語論をベースに証明
されたものは、意味論としても正しい、ということ。

- さて、このようなお話のもと、ゲーデルの不完全性
定理とは、
- ゲーデルの不完全性定理
形式的理論が次のふたつを満すならば、それが健全
かつ完全となるような解釈は存在しない。
- 自然数の理論を含む。
- 論理式が非論理的公理であるかどうかを決定可能
(turing decidable)である。
- ここで、PHL(PV,AV,S)が集合Sの決め方が任意なので、
結果として、ホーア論理はゲーデルの不完全性定理
を免れる、という。これはなんだかもやもやして理
解できていない。が、先に進もう。
** 5.1 ホーア論理の意味論
- あたりまえだが、完全性を議論するには、統語論と
意味論の両方が必要。
- ホーア論理については、表明の意味論は一階述語論
理に準ずるとして、プログラムの意味論と、表明付
きプログラムの意味論はまだ未定義である。
- それを定義していく。
*** 5.1.1 プログラムの意味論
- 「プログラムの意味論とは、プログラムの実行方法
を数学的に定義することである。」
- ここでは操作的意味論でやる。
- 操作的意味論は、抽象的なインタプリタを定義する
ようなものらしい。
- プログラムの操作的意味論の構成要素
- 1. ラベル付きプログラム (BNFで定義)
- 2. プログラムカウンタ
- 3. 状態 (変数の値を指定する)
- 4. 遷移関係 (実行の1ステップを記述する)
- 5. PVの解釈IP (式の意味を決める)
- 操作的意味論の語彙
- 状態(situation)とは、変数の値の状態であり、変
数から領域への関数によって表現されるものである。
これは表明の意味論における環境と同じものである。
よって、状態と環境を同義語とする。
- 状況(configuration)とは、状態とプログラムカウ
ンタの組<ρ,l>である。
- 遷移関係とは、プログラムの1ステップによって、
状況1から状況2に変わるときの状況1から状況2へ
の写像のことである。
- 実行とは、状況の列であり、その列の頭の状況のプ
ログラムカウンタは、プログラムの最初のラベルで
あり、それを起点遷移関係にて遷移する状況を並べ
たものである。頭の状況を初期状況と呼び、初期状
況を成す状態のことを、初期状態と呼ぶ。
- 次の状況とは、着目している状況から遷移関係に
て移りえる状況のことである。並列計算可能な言
語では、次の状況が複数になることがあるが、逐
次実行型言語では次の状況が2個以上となることは
ない。(2個になるのは条件分岐)。
- 遷移関係をプログラム言語の各文に対して定義する
のが、どうやら操作的意味論の要のようだ。
- Min言語の遷移関係を定義。
*** 5.1.2 Min言語の合成性
- まず原文まま引用。
---

Min言語の合成性

プログラム(文)の働きは部品の働きによって完全に決定
される。

---
- 働きというところが感覚的な記述になっているよう
な気がする。働きの語彙の定義が見当たらないので。
- おそらく、意味論(Semantics)のことではないか。
- ちょっと噛み砕きつつ、自分なりに正確にしたい。
- 部品は、証明の木の葉のことであった。
- プログラムの意味論(Semantics)の要は、遷移関係で
あった。
- それらを組み入れると、
---

Min言語の合成性

プログラム(文)の遷移関係は、そのプログラム(文)の部
品(証明木の葉)の遷移関係達によって完全に決定される。

---
- なんか、あまり嬉しくないな。こう書いてみても。

*** 5.1.3 実行関係による合成性の表現
- 「働き」ってもしかして副作用のことなのか?
- 語彙
- 実行関係:初期状態ρにてプログラムPを実行した
ときに、状態ρ'にて停止することを、Exec(P,ρ,
ρ')と書く。
- Min言語の各文について、実行関係にて初期状態
と終状態の関係を調べてみる。すると、Min言語
の合成性が実行関係としてもみてとれる。
- プログラムカウンタの合成性
原文まま引用。
---

プログラムカウンタの合成性

Min言語ではプログラムカウンタは、部分プログラムの
最初のラベルから入り、最後のラベルから出ていく。

---
- 構造化プログラミングとは、gotoやjumpを使わないこ
とによって、プログラムカウンタの合成性を極力維持
するようにするプログラミングスタイルである。(プ
ログラミング言語は問わない)
- 構造化プログラミングにてプログラムを書くことを目
的とするプログラミング言語は、構造化プログラミン
グ言語であるとみなされる。代表的なものに、C言語
やPascalがある。

*** 5.1.4 表明付きプログラムの意味論
- 語彙の「ホーア論理の解釈」とは、表明の語
彙の解釈のことである。その解釈をIと呼ぶ。
- 語彙の表明付きプログラム{A}P{B}の、解釈I
に対する部分正当性は、
---

∀ρ.∀ρ'.(I,ρ|= A => Exec[I'](P,ρ,ρ') => I,ρ'|= B)

ただしI'はIの語彙をPVに制限したものである。

---
と定義する。なお、これは原文からの引用ではない。
(誤字や脱字が多いため)


こつこつ。

【検証論】4 ホーア論理詳説 (その3)

4章のつづき。


** 証明アウトライン
- コメント付きプログラム
- 表明付きプログラムは、プログラムの前後に表明が
付くだけであり、プログラムに混在して表明は書
けない。
- 証明の木では、プログラムの各コンポーネントの前後
に表明がある。
- そこで、証明の木の各コンポーネントの表明付き
プログラムを証明の木の構造に従って合体して、
プログラムと表明が混在したものを書いちゃえ、
というアイデア。それをコメント付きプログラム
と言う。
- BNFで構文定義あり。ここに再掲はしない。
- 証明の木からコメント付きプログラムを作るときのア
ルゴリズムが掲載されている。これが、なんだかわか
りにくい。間違っているのでは?と思って、他の記
述を探したがなかなか見付からない。
- ただ、実際に証明木からコメント付きプログラムを生
成したり、変換したりするのは簡単であり、間違って
いないようだ。実体は理解できているのかもしれな
い。
- 証明の木の全ての表明を含んでいるものを完全証明ア
ウトライン、それから表明をさっぴいたものを証明ア
ウトラインという。さっぴきかたにルールはない。
さっぴきすぎると証明の木の復元が困難になる。

** プログラム変数と仕様変数
- 代入文の左辺に表れる変数はプログラム変数。表れ
ないのは仕様変数(論理変数とも)。
- プログラム変数はR/W。仕様変数はRead Only。
- 表明付きプログラムのプログラム本体部分の詳細が
不明なときであっても、仕様変数が何であるかの情
報があれば、表明の理解の助けになる。

** 整礎関係
- well-founded : 基礎のしっかりした
- 整礎関係の説明のところ、すっと入ってこない。私
の頭が悪いのだろう。。。
- Wikipedia: 無限降下列が存在しない2項関係を整礎関
係と言う。
- これはわかるこれをもとに自分なりに確認する。
- 述語<は自然数において整礎関係である。
x1<x0 ^ x2<x1 ^ x3<x2 ^ ... ^ xi+1<xi ^ ...
i.e. <(x1,x0) ^ <(x2,x1) ^ <(x3,x2) ^ ...
となる無限数列は存在しない。
- 述語>は自然数において整礎関係ではない。
x1>x0 ^ x2>x1 ^ x3>x2 ^ ... ^ xi+1>xi ^ ...
i.e. >(x1,x0) ^ >(x2,x1) ^ >(x3,x2) ^ ...
となる無限数列は存在しない。
- これでよしとする。

** 整礎表明
- 整礎表明の説明もすっと入ってこない。。。私の頭
が悪いのだろう。
- Web上でシンプルな説明をみつけた。これにて理解を
試みる。
- 。。。
- だめだ。シンプルすぎる。

- うーん。この完全ホーア理論の部分、どうもわかり
にくいと思い調べてみると、説明に誤りがあるとか、
不適切であるという指摘がWeb上に多少あった。
- ホーア論理についての情報がこの本以外ではほとん
どないのが現状。そこで巻末の参考文献をいくつか
取り寄せることにした。
- この部分はそれらの本が調達された後に再度チャレ
ンジしようと思う。


こつこつ。

2009年7月24日金曜日

【検証論】4 ホーア論理詳説 (その2)


** GCDプログラムの形式的証明を読む
- 読みました。。。
- 2ページ、証明的にいうと19行ですが、2時間かかり
ました。。。
- これは、慣れればかなり高速化が期待できますが、
ホーア論理の専門家になるのでなければ、慣れるこ
ともないように思います。
- 読む際のヒントをいくつか。
- 演算子優先度が普通に使われているので、Lisper
な人は、はじめに表明について括弧を補完した方が
読み易いです。
- [c/b][b/a][a/c]というのは、いわゆる変数の値の
スワップの表明代入版です。
- 13行のb /= 0は誤植かと。正しくは¬b = 0です。


** 再び、ホーア論理を組み立てた後の話

- 実際にGCDプログラムの証明を読んでみるとはっきり
わかるのですが、ホーア論理の要は帰結規則です。

- この帰結規則のところで、プログラムの正しさが、表
明が含意でつなげるかどうか(検証条件)ということ次
第である、という別れ目になります。

- すなわち、プログラムの正しさが、論理の問題に変
わるポイントなわけです。

- で、帰結規則というのは、先日掲載したとおりSにて
証明可能な検証条件は推論を進めてOKというものです。

- で、Sは、ホーア論理構築時に作成した解釈Iのもと
で正しい論理式の集合ということなので、なんのこ
とはない、解釈Iで検証条件が正しいかどうかを確認
することがやるべきことである。

- なので、非論理的公理を解釈Iから構築する場合は、
ホーア論理は、PV,AV,Iにて確定する。それゆえ、

PHL(PV,AV,I) ≡PHL(PV,AV,{F| I |= F})

と書くことにする。

- ヒルベルトの形式的証明の方法は、行同士が参照し
ている。これを図示すると木構造になる。

- この木構造を「証明の木 (proof tree)」と言う。

- 証明の木の葉を部品(コンポーネント)と言う。

- 証明の木の節を部分プログラムと言う。

- 証明の木の帰結規則でつながる部分を潰したものを
「構文木 (syntax tree)」と言う。


こつこつ。

2009年7月22日水曜日

【検証論】4 ホーア論理詳説

まず、4章は充填率が高いというか、手加減がないというか、前章で作った用語が入り乱れて記述されているので、刻んで読んでいくことすら難しい。なので自分なりにいろいろ展開して見える化しないと、私はとても理解できなかった。展開したものをここに書く。読書メモじゃなくて、そういうものなので、誤りを含んでいる可能性も高いと思う。


* 4 ホーア論理詳説
自分なりのポイントを自分なりに書く。

まず、ホーア論理を理解するために形式的理論を振り返っ
てみる。

** 形式的理論の骨組
形式的理論の骨組をできるだけシンプルに書く。
形式的理論を組み立てていく標準的な順番に沿って書く。
一階述語論理とする。

- 語彙を決める。
- 変数
- 定数
- 関数記号
- 記号
- アリティ
- 述語記号
- 記号
- アリティ
- 論理記号
整理の関係でここに書いたが論理記号は汎用的に
決まっているのでそれをそのまま採用するだけ。

- 構文を決める。
- 無手勝流 (自分で決める)
- 項の構文
- 論理式の構文
- 一階述語論理 (汎用的に決まっている)
- 項の構文
- 論理式の構文

- 語彙の解釈を決める。
- 真理値集合:{True,False}が存在するとする。こ
れはお約束。
- 領域:領域を決める。
- 定数:領域の要素と定数を紐付ける。
- 関数記号:領域上の関数と関数記号を紐付ける。
- 述語記号:領域上の述語と述語記号を紐付ける。
- 述語記号"="は必ず領域における等価関数に紐付
けること。

- 形式的理論の公理を決める。
ここがAIMAと違う。AIMAはこれらを伴意と真理値表
から導き出す。プログラム検証論は公理として与え
る。
- 公理(I群) (論理的公理)
- これは、一階述語論理としては確定している。お
約束。
- 公理(II群) (非論理的公理)
- これは、今構築している内容に合わせて定義す
る。これは構文で許される範囲で、理論を構築
するものが自由に選ぶものである。自由に選ぶ
というのは、この時点では特定の解釈との整合
性は求められていないから。それは理論を作っ
た後の検査課題である。
- 推論規則
- これは一階述語論理としては確定している。お約
束。

- 形式的証明の方法を決める。
- プログラム検証論ではヒルベルトの方法を採用し
ている。
- 他に自然演繹などがある。

** 形式的理論のトピック
前項で形式的理論の骨組が整理できた。ここでは、この
上でどのようなトピックがあるのか、列記する。

- 環境と項の解釈
- 項の解釈には環境を使う。
- 論理式Aは解釈Iと環境pに対して正しい、ということ
を、

I,p |= A

と書く。

- 論理式Aは解釈Iと任意の環境に対して正しい(伴意?)
ということを、

I |= A

と書く。

- トートロジー。任意の解釈Iに対して I |= A が成立
するとき、Aをトートロジーと呼ぶ。

- 形式的に証明可能
- 形式的理論Tにおいて、形式的証明によって論理式
を証明できたとき、

T |- その論理式

と書く。

- 形式的理論Tが解釈Iにおいて完全性と持つというこ
とは、

任意の論理式Fに対して、I |= F ならば、T |- F と
なる

ということである。すなわち意味論としての正しさ
があるものは、統語論としての正しさも証明できる
ことが保証されているということ。

- 形式的理論Tが解釈Iに対して健全であるとは、

任意の論理式Fに対して、T |- F ならば、I |= F と
なる

ということである。すなわち統語論をベースに証明
されたものは、意味論としても正しい、ことが保証
されているということ。

- 形式的理論として一階述語論理を採用した場合

- 次の2つのことが重要。
- 一階述語論理の論理的公理はすべてトートロジー
である。
- 一階述語論理の推論規則は、前提が真ならば結論
も真である。
- これらゆえ、次が言える。
- 一階述語論理に基づく形式的理論Tが解釈Iに対し
て健全である必要十分条件は、Tの非論理的公理
のすべてにてついて(今そのひとつをFとする)に
対して、I |= Fが成り立つことである。
- 一階述語論理自身の健全性と完全性
- 一階述語論理をつかって作った形式的理論の健全
性/完全性と、一階述語論理自身の健全性/完全性
とは別の概念である。
- 一階述語論理の健全性とは、一階述語論理の公理
およびそれから推論される論理式(定理)はすべて
トートロジである、ということ。
- 一階述語論理の完全性とは、 一階述語論理の定理
の証明は、一階述語論理以外の情報を必要としな
い、ということ。
- ゲーデルの不完全性定理
形式的理論が次のふたつを満すならば、それが健全
かつ完全となるような解釈は存在しない。
- 自然数の理論を含む。
- 論理式が非論理的公理であるかどうかを決定可能
(turing decidable)である。

** 形式的理論としてホーア論理を組み立てる

前項の一階述語論理の組み立てを頭のすみにおきつつ、
ホーア論理を形式的に組み立てる。
前置きを少々。部分正当性ホーア論理をPHL、完全正当
性ホーア論理をTHLと書く。ここではPHLをやる。結論か
ら先に言うと、PHLを決めるということは、PV,AV,Sを決
めるということにほぼ等しい。よって、特定化されたホー
ア論理のことをPHL(PV,AV,S)と書く。

- ホーア論理の語彙を決める。
- プログラムの語彙(PV)を決める。
- ただし、プログラムの語彙の論理記号は限量子
を含まない。
- これは、ユニークなものではない。すなわち、
いろいろなPVを考えることができて、それぞれ
がそのプログラミング言語の(を使った)ホーア
論理となる。
- 実践的に言うと、プログラムの語彙は、2つの部
分で構成される。ひとつは数やそれに関する関数
記号/述語記号を定めるもの。もうひとつは、そ
れらを組み込みつつプログラムを表現するための
プログラミング言語を定めるもの。例えば、整数
に関する問題しか解かなないのであれば、前者は
整数の語彙を採用する。例えば、浮動小数点数に
関する問題を解くならば、浮動小数点の語彙を採
用する。どちらでもプログラミング言語は同じも
の、というのもありえる。また、前者が同じだが、
プログラミング言語がPascal 風であったりLisp
風であったりいう形で、トータルでは別のもので
あることもある。
- 表明の語彙(AV)を決める。
- AVはPVの拡張でなければならない。
- AVの変数記号はPVと同じでなければならない。

- ホーア論理の構文を決める。
- プログラムの構文を決める。
- 項の構文を決める。これが式となる。
- 論理式の構文を決める。これがブール式となる。
- 表明の構文を決める。
- 表明付きプログラムの構文を決める。

- 表明の非論理的公理を決める。
- これは、あたりまえだが、AVを語彙とする論理式の
集合Fml(AV)の部分集合である。それをSと呼ぶ。
- 非論理的公理は表明付きプログラムの前後部分に
ある表明を指定するために使われる。
- 非論理的公理は、公理といいつつ、解釈まで降り
ていって決める。

- 推論規則を決める。

- 形式的証明の方法は決まっている。
- 次のものに固定されているようだ。

---
ホーア論理の形式的証明

PHL(PV,AV,S)が特定されているとする。そのPHLにおけ
る形式的証明とは、行番号、表明付きプログラムAP、コ
メントCからなる行を並べたもので、次の条件を満たす
ものをいう。

1. i行目のコメントCiが公理の番号であるとき、その行
の表明付きプログラムAPiはその公理である。
2. i行目のコメントCiが推論規則の番号と数の列
R,j1,...,jmであるときは、j1,...,jm < i であり、

APj1,...,APjm
---------------
APi

が、その推論規則Rとなる。
---

- ここまでで統語論の構築が完了。これに続き意味論の
構築が存在する。(それは次章のようだ)


** とあるホーア論理をこの手順に従って組み立ててみる

GCDプログラムの検証につかえるホーア論理を構築する。
ここでは統語論を扱う。(意味論的なことも、ちょろっ
と出てくる)


- ホーア論理の語彙を決める。
- プログラムの語彙(PV)を決める。

---
整数の語彙(VZ)

変数:a,b,c,aa,ac,a0,b01,ac123,... .
定数:0,1.
関数記号:+,*,-.mod.
述語記号:=,<=.
---
- ただし、プログラムの語彙の論理記号は限量子
を含まない。
- アリティはすべて2。
- 表明の語彙(AV)を決める。
- AVはPVの拡張でなければならない。

---
AVはPVに次の語彙を加えたものとする。

関数記号:gcd,abs.
述語記号:<.

gcd,<はアリティ2。absはアリティ1。
---

- ホーア論理の構文を決める。
- プログラムの構文を決める。
- 項の構文を決める。これが式となる。
- 論理式の構文を決める。これがブール式となる。

---
Term(PV)、Fml(PV)は一階述語論理の項の統語論を採用する。
---

---
プログラミング言語 Min(PV)

変数 ::= 語彙PVの変数.
式 ::= Term(PV)の項.
ブール式 ::= Fml(PV)の原子論理式 | ブール式 ^ ブール式 |
ブール式 v ブール式 | ブール式 => ブール式 |
¬ブール式.
文 ::= skip | 変数 := 式 | begin 文 { ";" 文 } end |
if ブール式 then 文 else 文 fi |
while ブール式 do 文 od.
プログラム ::= 文.
---

- 余談:ここで、beginとかifとかはあくまでプログ
ラミング言語の構文要素であり、式ではない! 非
Lisp系の言語にてどういう事情や文脈にて式ではな
い構文要素が出てくるのだろうかとモヤモヤしてい
たが、ここでの出現は、その必然性をこの文脈にお
いて感じさせるものだ。この気づきはありがたい。

---
PHL(PV,AV,S)の公理と推論規則

公理

Aas(代入文の公理)
{A[t/x]} x := t {A}

Ask(スキップ文の公理)
{A} skip {A}

推論規則

Rif(条件文の規則)
{C^A}P{B} {¬C^A}Q{B}
-----------------------------
{A} if C then P else Q fi {B}

Rwh(while文の規則)
{C^A}P{A}
-----------------------------
{A} while C do P od {¬C ^ A}

Rcp(複合文の規則)
{A}P1{S1}...{Sn-1}Pn{B}
-----------------------------
{A} begin P1;...; Pn end {B}

Rcs(帰結規則)
{B}P{C}
---------
{A}P{D}
ただし、S |- A => B かつ S |- C => D であるとする。
---

- 表明の構文を決める。
- 表明付きプログラムの構文を決める。

---
表明と表明付きプログラムの定義

表明 ::= Fml(AV)の論理式.
表明付きプログラム ::= "{" 表明 "}" プログラム "{" 表明 "}".

ただし、Term(AV),Fml(AV)については一階述語論理の項
の統語論を採用する。
---

- 表明の非論理的公理を決める。
- これは、あたりまえだが、AVを語彙とする論理式の
集合Fml(AV)の部分集合である。それをSと呼ぶ。
- 非論理的公理は表明付きプログラムの前後部分に
ある表明を指定するために使われる。
- 非論理的公理は、公理といいつつ、解釈まで降り
ていって決める。
---
まず、PVの語彙の解釈を決める。

領域: D=N.Nは自然数の集合を表す。
定数: I[0]=0, I[1]=1.
関数記号: I[+]="+", I[*]="*",
I[mod](a,b) =
0 b = 0のとき
aをbで割ったときの余り それ以外のとき.
述語記号: I[=]="=", I[<=],


次に、これをベースにAVで追加したものの解釈を決める。
これでAVの解釈が構築完了となる。

関数記号:
I[gcd](a,b) =
0 a=b=0であるとき
aとbの最大公約数 それ以外のとき.
I[abs](a) = aの絶対値
I[<](a,b) =
True a < bであるとき
False それ以外のとき


最後に非論理的公理を決める。これは、この解釈にて正
しい論理式全てである。集合表記すると次のとおり。

{F| I |= F}

これをSと呼ぶ。
---

** ホーア論理を組み立てた後の話

- ここまで組み立てるとP90にあるGCDプログラムの形
式的証明をすんなり読むことができる。


これ以降は後日。

こつこつ。

2009年7月19日日曜日

【検証論】3 形式的理論

3章が終わった。
大変勉強になった。この章は今までの形ではブログには載せられない。理由をいくつか。

  • 取ったメモは、本文のほぼ丸写し。自分の言葉では無い。これは載せられない。
  • 途中から紙と鉛筆になった。論理記号を端末でうまく入力できない。


そこで、トピックをいくつか。

  • 前のエントリで書いたように、形式理論または一階述語論理にたいする大変よい解説である。
  • ただし最後の方は著者の息切れ感があり、多少表現が雑なところや、誤字・脱字があるので要注意。
  • 項の代入性のところがモヤモヤしている。というのはそもそも代入の定義のところが曖昧に記述されているからだ。


プログラム検証論は私にとってそれなりにごついので時間がかかりそうだ。
そこで、刻んでいくことにする。その代わり並行して別の本にも取り組もうと思う。

こつこつ。

2009年7月16日木曜日

【検証論】3 形式的理論

プログラム検証論、すごい。。。
この3章 形式的理論ほど、慈愛に満ちて、簡にして要を得た
形式的理論の導入をみたことがない。

昔の自分はそれがわからなかった。今はわかる。

2009年7月15日水曜日

【検証論】2 ホーア論理入門


* 2 ホーア論理入門
** 2.1 表明付きプログラム
- ホーア論理では、表明付きプログラム(asserted
program)というものを書く。

{A}P{B}
<A>P<B>

のごとく。Pはプログラム本体であり、それを囲むも
のは一種の仕様(そのプログラムに関する)である。
- Aを前条件(precondition)、Bを後条件
(postcondition)と言う。
- <A>P<B>は、Pが停止し、どちらも真になることで全
体が真となる。(完全正当性)
- {A}P{B}は、Pが停止たときにA,Bどちらも真になると
きに真であり、Pが停止しないときも真である。(部
分正当性)
** 2.2 表明とコメント
- 表明って、コメントで関数の入出力仕様を書くのと
同じだよね。
** 2.3 部分正当性と完全正当性
- 完全正当性 = 部分正当性 + 停止性.
- ホーア論理では、主に部分正当性を扱う。
** 2.4 表明付きプログラムの正しさの証明
- 表明付きプログラムの正しさの証明は、公理と推論
規則にて実施する。
*** 2.4.1 正しさの証明とプログラムの分割
- プログラムは部分的なプログラムから出来ている。
- ホーア論理は部分的なプログラムの正しさを証明で
きれば、プログラム全体の正しさが証明されるよう
になっている。
- Common Lispにとってホーア論理ってどうなのかなぁ。
*** 2.4.2 複合文の正しさ
- 分割しやすいようにver2を書き換える。

---
;; { 整数x,yの少なくとも一方はゼロでない。 }
(defun gcd-ver2 (x y)
(progn
(setf a x)
(setf b y)
(while (/= b 0)
(progn
(setf a (mod a b))
(setf c a)
(setf a b)
(setf b a)))
(if (> a 0)
a
(- a))))
;; {変数aの値はxとyの最大公約数である。}
---

- こいつを分割した。

---
;; AP1:
;; {整数x,yの少なくとも一方はゼロでない。}
(setf a x)
;; {変数aの値はxである。
;; ただし、整数x,yの少なくとも一方はゼロでない。}

;; AP2:
;; {変数aの値はxである。
;; 整数x,yの少なくとも一方はゼロでない。}
(setf a x)
;; {変数a,bの値はlx,yである。
;; ただし、整数x,yの少なくとも一方はゼロでない。}

;; AP3:
;; {整数a,bの値はx,yである。
;; ただし、整数x,yの少なくとも一方はゼロでない。}
(while (/= b 0)
(progn
(setf a (mod a b))
(setf c a)
(setf a b)
(setf b a)))
;; {|a|はxとyの最大公約数である。}

;; AP4:
;; {|a|はxとyの最大公約数である。}
(if (> a 0)
a
(- a))
;; {変数aの値はxとyの最大公約数である。}
---

- ホーア論理:複合文の規則

この本のもの
{A}P1{S1}...{Sn-1}Pn{B}
-------------------------
{A}begin P1;...;Pn end{B}


Common Lisp用
{A}P1{S1}...{Sn-1}Pn{B}
-------------------------
{A}(progn P1 ... Pn){B}

*** 2.4.3 代入文の正しさ
- ホーア論理:代入文の公理

この本のもの
{A[t/a]} a := t {A}

Common Lisp用
{A[t/a]} (setf a t) {A}

- うお。公理なのね。
- A[t/a]は、表明Aの中の項aをtで置換えたもの。
- この公理の形でAP1の代入を書いてみよう。
;; AP1:
;; {変数xの値はxである。
;; ただし、整数x,yの少なくとも一方はゼロでない。}
(setf a x)
;; {変数aの値はxである。
;; ただし、整数x,yの少なくとも一方はゼロでない。}
- になるらしい。これなんか変? しらべる。
- A[x/a]は、表明Aの中の項aをで置換えたもの。
- そうすると表明Aはなんだっけ?となる。
- 表明Aは後条件のことだからそれにしたがっ
て書く。

A は {変数aの値はxである。
ただし、整数x,yの少なくとも一方はゼロでない。}
- そうすると、後条件から導き出した前条件は、

A[x/a] は {変数xの値はxである。
整数x,yの少なくとも一方はゼロでない。}である。
- なので常に真となる代入文の形で、これらを書くと、

;; {変数xの値はxである。
;; 整数x,yの少なくとも一方はゼロでない。}である。
(setf a x)
;; {変数aの値はxである。
;; 整数x,yの少なくとも一方はゼロでない。}である。
- 変数xの値がxであるのは自明とすれば、これはAP1と
同じである。よって、AP1は正しい。
- うーん。だからどーした、という感じ。
- AP2についてやってみる。

AP2は、

;; AP2:
;; {変数aの値はxである。
;; 整数x,yの少なくとも一方はゼロでない。}
(setf b )
;; {変数a,bの値はx,yである。
;; ただし、整数x,yの少なくとも一方はゼロでない。}

である。これが正しいことを証明する。証明はこのAP2
が代入文の公理の形式として適格であることによって示
す。

まず後条件Aは次のとおりである。

;; {変数a,bの値はx,yである。
;; ただし、整数x,yの少なくとも一方はゼロでない。}

代入文はbにyを代入しているので、前条件はこれのbをx
に変えたものである。

;; {変数a,yの値はx,yである。
;; ただし、整数x,yの少なくとも一方はゼロでない。}

変数yの値がyのことは自明なので、この前条件は次のも
のと同じと考えてよい。

;; {変数aの値はxである。
;; ただし、整数x,yの少なくとも一方はゼロでない。}

これはAP1の前条件と同一である。ゆえにAP1は代入文の
公理にすぎない。よってこれは真である。

*** 2.4.4 表明の置き換え
- ホーア論理:帰結規則

AならばB {B}P{C} CならばD
-------------------------
{A}P{D}

*** 2.4.5 while文の正しさ
- ホーア論理:while文の規則

{"式tの値は真" and A}P{A}
--------------------------------------
{A} while t do P {"式tの値は偽" and A}

- Aはループ不変表明と呼ぶ。こいつがポイント。これ
に何をえらぶかでwhileの正しさを証明できるかどう
かがきまる。ここでは、

gcd(a,b) = gcd(x,y)

を選ぶ。
するとwhile文の規則の前条件は、

;; {"式(/= b 0)の値は真" and gcd(a,b) = gcd(x,y)}
(progn
(setf a (mod a b))
(setf c a)
(setf a b)
(setf b a))
;; {gcd(a,b) = gcd(x,y)}

となる。このPは地道に計算をすれば正しいことがわか
る。そこで、これを推論規則にしたがってゴールに変
換する。

;; {gcd(a,b) = gcd(x,y)}
(while (/= b 0)
(progn
(setf a (mod a b))
(setf c a)
(setf a b)
(setf b a)))
;; {"式(/= b 0)の値は偽" and gcd(a,b) = gcd(x,y)}

これは推論規則により正しいプログラムである。さて、
この後条件は、b = 0なので、gcd(a,b)が|a|になるこ
とから、AP3と同じである。よって、AP3も正しい。

*** 2.4.6 条件文の正しさ
- whileよりは簡単だ。

{"式tの値は真" and A}P{B}
---------------------------
{A}if t then P fi{B}

{"式tの値は真" and A}P{B} {"式tの値は偽" and A}Q{B}
-----------------------------------------------------
{A}if t then P else Q fi{B}

- Common Lisp版は割愛。
- 推論規則で、このように併記される場合は、andの意
味かな。

** 2.5 whileプログラムのホーア論理
- 複合文、代入文、while文、条件文だけでできている
プログラムをwhileプログラムと言う。
*** 2.5.1 合成性
- ホーア論理(の照明)は、部品の正しさに還元できる。
これを合成性と呼ぶ。
*** 2.5.2 公理・推論規則と文の対応
- ホーア論理の使い方の整理。
- まず、帰結規則以外の規則は逆向き推論の方法は
確定している。よって、プログラムをホーア論理
で分析するときの初手として、プログラムを部品
に分解していくわけだが、その分解する単位とい
うか分解の仕方はまあ決まってしまうということ。
- ただし、分解した後に間をつなぐ前条件とか後条
件を部品につけるわけだが、これは発案しなけれ
ばいけない作業。
- また、whileに対するループ不変量も発見しなけれ
ばいけないものである。
- まとめると、プログラムの書きぶりを反映した分解
と、各種条件(表明)を発見的に立案する作業(ここ
で必要に応じて帰結規則をつかる)が第一ステップ
として存在する。
- あとは、立案した表明が正しいこと証明できるか
どうかである。それが証明できれば、プログラム
の正しさは証明されたことになる。
** 2.6 完全正当性の証明
- while文の規則以外は部分正当性の規則と公理がその
まま適用できる。まあ、ループ無いしね。
- while文の規則の完全正当性版。

<bound = n and "式tの値は真" and A>P<bound < n and A>
-------------------------------------------------------
<A> while t do P <"式tの値は偽" and A>

ここで、boundは非負整数を表す式(数学的な式でよい)
であり、nは非負整数を表わす変数である。nはPの中に
登場してはいけない。

- これを自分なりに読む。これは、停止するwhileは上
段のように書けるということを教えてくれている。逆
にこの上段のように書けなければ、そのwhileが停止
するかどうかはわからない。さて、上段のように書け
るということはどういうことなのか読み解く。それは、
Pの処理に絡み仮にboundと呼ぶ非負の量が存在してい
ることをまず求めている。そのboundという量は、Pの
処理によって処理前より小さくなるというような量だ。
かつ負にはならないことも条件付けされている。さて、
そういう量が実際に存在したとしよう。下段に目を移
すと、それはPの背後にいる隠れた値とも考えられる。
処理Pを下段のようにwhile文で繰返し実行したとする。
すると隠れた変数boundは、Pを一回処理するごとに小
さくなり、かつ非負である。さて、具体的にnが何で
あるかは、boundの定義によるわけだが、上段が常に
成立するといことは、bound = 0ということが起り得
ないということであるから?、下段のwhile文は停止
すると言える。??? なんだかよくわからん。

*** 2.6.1 ループの限度についての注意
- うーん。Lispのプログラミングだと、ループを再帰で
書くときに、再帰が必ず停止するように注意するこ
とに相当すると思うんだけど、なんかそれを回りく
どく扱っているように思える。
- ループ不変量についても、第一義にはproperly tail
recursiveに書けますか、というような気がする。た
だ、properly tail recursiveじゃなくてもループ不
変量が存在するというならばそれはおもしろい事実
ではある。
** 2.7 ホーア論理の能力
*** 2.7.1 whileプログラムの相対完全性
- うーん。よくわからん。ホーア論理の実体が何であっ
て、それが証明する正しさが何かがいまいちピンと
こない。だからwhileプログラムの相対完全性もピン
とこない。これは形式化をやればいいかな、という
ことで次章に送る。

*** 2.7.2 ホーア論理とプログラム検証の限界
- Algol-likeの意味にびっくりした。
- 1.手続き定義可能。局所手続きも定義可能。
- 2.手続きを引数として渡せる。
- 3.再帰呼び出し可能。
- 4.静的スコープが可能。
- 5.大域変数可能。
- Algol記法というのは文とコードブロックを多様する
統語論に対するものだと思うが、言語機能で言うと、
Algolって普通に関数プログラミングができる言語な
んですね。


ホーア論理は命令型プログラミングを対象としていることがわかった。

こつこつ。

2009年7月14日火曜日

【検証論】1 プログラムの検証

自分なりにエッセンスを抽出して、自分なりに書く。

* 1 プログラムの検証
** 1.1 本書の目指すところ
- プログラムの正しさ、ということ自体を明確にする。
- 形式的技法(実用可能なプログラム検証論)への入口
になる。
** 1.2 プログラム検証論の目的
- プログラマが、自分が正しく作ったと言っても正し
さの証明にはならない。
- 権威あるアルゴリズムを使っているから大丈夫、と
言っても正しさの証明にはならない。
- ソースコードを単純に開示するだけでは、正しさの
証明にはならない。(それを見る人がどう見るかにも
よるが)
- テストは検証の手法のひとつであるが、正しさの証
明にはならないことが多い。
- お題としてのGCD。

GCD プログラム ver.1:
---
begin
a := x; b := y;
while b != 0 do
a := a mod b;
c := a; a := b; b := c
end
end
---
これ、言語、なんだろ? Pascal?
- ユークリッドのアルゴリズムって何だっけ?
- ユークリッドの互除法
- 2つの自然数m,nの最大公約数を求める。
- m>nとする。
- m = q0 n + r1 (0 <= r1 < n)
- とする。
- r1 が0でなければ、次のようにする。
- n = q1 r1 + r2 (0 <= r2 < r1)
- 同様のことを続ける。
r1 = q2 r2 + r3 (0 <= r3 < r2)
r2 = q3 r3 + r4 (0 <= r4 < r3)
- r1>r2>...なので、今、自然数について扱っている
ことからrk>0,rk+1 = 0となるkが存在する。
rk = qk rk
このqkが、m,nの最大公約数である。
- 自分なりの言葉でポイントを。
- m = q0 n.であればnが最大公約数だよね。
- m = q0 n + r1.と余りがでちゃった。
- そうすると、m,nの最大公約数というのは、nとr1の
最大公約数になる。なんで? それをgとすれば、
- m = q0 a g + b g.
= (q0 a + b) g.

になるから、mもgで割り切れる。で、gを1でも大き
くしたら、mは割り切れない。なぜかというそれが、
gがn,r1の最大公約数ということだから。
- なるほど。再帰的なんだな。
- Common Lispで書いてみる。

---
(defun mygcd (m n)
(if (> m n)
(gcd-aux m n)
(gcd-aux n m)))

(defun gcd-aux (m n)
(let ((r (mod m n)))
(if (= r 0)
n
(gcd-aux n r))))
---

とか。

---
(defun mygcd2 (m n)
(labels ((g (a b &optional (r (mod a b)))
(if (= r 0)
b
(g b r))))
(if (> m n)
(g m n)
(g n m))))
---

とか。サンプルをそのままCommon Lispにもってくると、

---
(defun gcd-ver1 (x y)
(let ((a x)
(b y))
(while (/= b 0)
(setf a (mod a b))
(setf c a
a b
b c))
a))
---

とか。そうか、引数の大小は一回目のmodで対処される
んだな。

** 1.3 プログラムの正しさを証明する
- で、これらプログラムが最大公約数を計算すること
を数学的に証明したい、ということ。
- うーん。この本に書かれている例がプログラムの動
作の証明、なのか。。。まあ確かに数学の証明っぽ
い感じはするが。なんか釈然としない。
- というのは、やはり、もともとそういう証明を考え
ることがプログラムを作るときに考えることじゃな
いかなぁ、というのがあり。
- さて、負の整数に対する公約数の定義は何だろう。
- まず除法定理。
- 任意の整数a,b(b>0)に対して、a = q b + r (0 <= r
< b)となる整数q,rがただ一組存在する。
qを、aをbで割った商(quotient)、rを剰余
(remainder)と呼ぶ。
- 次に、約数の定義。
- a,b(b/=0)について、a = q bとなる整数qが存在する
とき、bはaの約数であるという。
- 次に、最大公約数の定義。
- どれかは0でない整数a1,...,anの共通な約数を公約
数といい、正の公約数のうちで最大のものを最大公
約数と呼ぶ。
- すると、a,bともに正の場合は簡単だが、負が入る場
合はどうなるのかな。a,b(a<0,b>0)の場合、a = q b
だとすると、qも負であるがこの式は成立しているこ
とは間違いない。すると、b = 1 bでもあるからbは
a,bの公約数である。これしか公約数が無いとき、こ
れを最大公約数と呼びたくなるが、最大公約数の定
義によると資格があるのは正の公約数だけではない
か。こまった。
- 以上は岩波数学辞典の話。
- そこで、CRC Encyclopedia of Mathematicsをみる。
- こちらはgcdは正の整数について、と定義されている。
- 情報処理ハンドブックにはgcdのエントリが無い。
- うむー。困ったもんだ。
- ここでは、著者の言うとおり、負の整数が絡む最大
公約数は正負を逆転させると鵜呑みにしよう。

---
(defun gcd-ver2 (x y)
(let ((a x)
(b y))
(while (/= b 0)
(setf a (mod a b))
(setf c a
a b
b c))
(if (> a 0)
a
(- a))))
---

- ところで気になるのが、剰余定理とCommon Lispの
modとremの関係。
- ためす。

CL-USER(18): (mod -7 3)
2
CL-USER(19): (rem -7 3)
-1
- すると

-7 = -3 * 3 + (mod -7 3)
-7 = -2 * 3 + (rem -7 3)

であるから、剰余としてはmodがばっちり。よかった。

** 1.4 仕様:正しさの基準
- おお、公約数って負の整数についても存在するのね。
- ソフトウエアは要求を満足しなければいけない。
- 要求に合わない仕様は間違いである。
- 要求に合わない仕様に基づくプログラムは間違いで
ある。
- 要求に合う仕様に基づかないプログラムは間違いであ
る。
- 要求に合わない仕様に基づかないプログラムは間違い
であるかどうかはわからない。
- この本では仕様に対するプログラムの正しさだけを
扱う。ちなみに形式的手法では、仕様の正しさもプ
ログラムと同等以上に扱う。

** 1.5 本書の組み立て
- 特になし。


こつこつ。

プログラム検証論を読む

AIMAをかじったところ、論理について少し見通しがでてきた。

そこでこれを機会にプログラム検証論の基本も見ておこうと思う。

本はこれ。

プログラム検証論

仕事の中でも、書籍の中でもユニットテストとか検証とかでてくるのですが、一度数学的見地がどうなっているのかみてみたいなぁと思ってました。

というわけで、こつこつ、再開します。