2009年7月31日金曜日

【DBiD】5 リレーショナル代数 (その4)


** 5.6 式の変換
- リレーショナル式を同値な別のリレーショナル式に
変換していく。それがオプティマイザの役割のひと
つでもある。
- 式の変換の例。
- 「部品P2を供給するサプライヤを、供給する部品
数とともに取得する」クエリ。

((S JOIN SP) WHERE PNO = PNO('P2')) {ALL BUT PNO}

- 濃度について、S:100、SP:100万、SPのうちP2であ
るのが500という状況を考える。
- この式を単純に評価すると次の手順となる。
- 1. SとSPを結合する。
- Sをread。(100タプル read)
- SひとつごとにSPをread。(100万タプル read)
- 結果として100万個のタプルをwrite。(100万タ
プル write)
- 2. 1の結果を制限する。
- 結果としての100万個のタプルをread。(100万
タプル read)
- 制限として500個がピックアップされ、それは
writeせずにメモリ保持と見做す。
- 3. 2の結果を射影する。
- これはメモリ上の処理。
- この手順でのタプルI/O数は、次の計算のとおり。
(+ 100
(* 100 1000000)
1000000
1000000) ; => 102000100
- 別の手順を考える。
- 1. SPを部品P2のタプルだけに制限する。
- SPで100万タプルread。
- 結果の500タプルはメモリ保持。
- 2. 1の結果とSを結合。
- Sで100タプルread。
- 結合してできた500タプルはメモリ保持。
- 3. 2の結果を射影する。
- これはメモリ上の処理。
- この手順でのタプルI/O数は、次の計算のとおり。
(+ 1000000
100) ; => 1000100
- I/Oの差。
(/ 102000100.0 1000100) ; => 101.98990100989901
- 2つめの手順を素直に表すように式を書き換える。

((S JOIN SP) WHERE PNO = PNO('P2')) {ALL BUT PNO} ; もともと
(S JOIN (SP WHERE PNO = PNO('P2'))) {ALL BUT PNO} ; 変更版

- オプティマイザというのはこういうことを知って
いて、その知識をもとに式変換を実施する。

- 式変換に使えるのはリレーショナル代数の演算子
どうしの性質である。
- 分配則
- 可換則
- 結合則
などがある。
- リレーショナル代数における最適化はDBの実装(物
理構造)によらない。


牛歩のごとくだなぁ。
こつこつ。

【JT】2 オブジェクト指向プログラミングの概念


* 2 オブジェクト指向プログラミングの概念
** オブジェクトとは
- 現実世界のオブジェクトのすべてに状態と振る舞いが
あるでしょ、ソフトウエアのオブジェクト指向はそれ
と同じだよ、という導入はいただけない。自然をそう
見たときそれはすでにオブジェクト指向の結果なんだ
から、結果をもって原因と言われても。。。
** クラスとは
- クラスのインスタンス = オブジェクト.
- うーん。ここの説明でクラスを理解するのは無理だ
ろう。私はCLOSをかじっているので大丈夫だが。
** 継承とは
- Javaでは、クラスの継承にて、親は常にひとつ。多
重継承は無いようだ。
- インターフェイスはクラスと外部世界との契約であ
る。この契約はビルド時にコンパイラによって強制
される。
** パッケージとは
- クラスとインターフェイスを整理するための名前空
間。
- クラスライブラリは、パッケージの集合。
- クラスライブラリはAPIとも呼ぶ。
** 設問と演習
*** 設問
- 1. 状態 振舞
- 2. フィールド
- 3. メソッド
- 4. カプセル化
- 5. クラス
- 6. スーパークラス extends サブクラス
- 7. インターフェイス
- 8. パッケージ
- 9. Application programming interface
*** 演習
- 1. こんな感じ?
---

class Radio {
int power = 0; // 0: off 1: on
int stationId = 0;
int volume = 0; // [0,10]
int volumeUnit = 1;

void togglePower() {
if (power == 0) {
power = 1;
} else {
power = 0;
}
}

void changeStationId(int newValue) {
stationId = newValue;
}

void volumeUp() {
if (volume < 11) {
volume += volumeUnit;
}
}
void voludeDown() {
if (volume > 0) {
volume -= volumeUnit;
}
}

void printStates() {
System.out.println("power:" + power +
" station id:" + stationId +
" volume:" + volume);
}
}

---

- 2. あり? エラーが出る。なんでだろ。

---
interface AVEquipment {
void volumeUp();
void volumeDown();
}

---
___

class Radio implements AVEquipment {
int power = 0; // 0: off 1: on
int stationId = 0;
int volume = 0; // [0,10]
int volumeUnit = 1;

void togglePower() {
if (power == 0) {
power = 1;
} else {
power = 0;
}
}

void changeStationId(int newValue) {
stationId = newValue;
}

void volumeUp() {
if (volume < 11) {
volume += volumeUnit;
}
}
void volumeDown() {
if (volume > 0) {
volume -= volumeUnit;
}
}

void printStates() {
System.out.println("power:" + power +
" station id:" + stationId +
" volume:" + volume);
}
}

___

こんなエラーが出る。

---

-*- mode: compilation; default-directory: "~/scratch/java/the-java-tutorial/ClassIntroduction/" -*-
Compilation started at Fri Jul 31 20:45:18

javac Radio.java
----------
1. ERROR in Radio.java (at line 19)
void volumeUp() {
^^^^^^^^^^
Cannot reduce the visibility of the inherited method from AVEquipment
----------
2. ERROR in Radio.java (at line 24)
void volumeDown() {
^^^^^^^^^^^^
Cannot reduce the visibility of the inherited method from AVEquipment
----------
2 problems (2 errors)
Compilation exited abnormally with code 255 at Fri Jul 31 20:45:20

---


こつこつ。

【JT】1 はじめてのJava


* 1 はじめてのJava
** Javaテクノロジ現象
- Javaはテクノロジであるとともにプラットフォーム
である。
** はじめてのJavaプログラミング
- NetBeans IDEの紹介。NetBeans IDEは使わないので
スキップ。
** はじめの一歩 (Microsoft Windows)
- スキップ。
** はじめの一歩 (Solaris OS, Linux)
- バージョンチェック。問題なさげ。
the-java-tutorial $ java -version
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) 64-Bit Server VM (build 11.0-b15, mixed mode)
the-java-tutorial $
- HelloWorldApp、問題なし。

** Hello Worldプログラムを解剖する
- 特になし。

** エラーの説明
- 特になし。

** 設問と演習
*** 設問
- 1. バイトコード.
- 2. c.
- 3. HelloWorldApp.classが存在するかどうか。
*** 演習
- 1.
---

class HolaMundoApp {
public static void main(String[] args) {
System.out.println("Hola Mundo!");
}
}

---

- 2. "が漏れている。


既視感が激しいと思ったらProcessingがJavaだった。この前やったばかり。
こつこつ。

Javaを学ぶ

意図あって、Javaをちょこっと学んでみようと思う。

本は、

Javaチュートリアル

にする。この本がものすごいよさそう、というわけではないのだが(悪そうというわけでもない)、公式チュートリアルがあるなら、まあそれをやるべし、という選定。

あまり根を詰めずにゆるくやりたい。

2009年7月30日木曜日

本日の基礎トレ


  • 微積分 :Calculus
    (15/596)
    ※問題のうち、*と**はやらない。

  • 線形代数:線型代数
    (30/333)

  • 位相空間:はじめよう位相空間
    (10/182)

  • 計算練習:コンピュータの数学
    (4問)
    ※これはページ数による進捗管理が適さないことがわかった。問題にどんどん取り組んで、それに解答できるように本文を理解していく、という問題駆動がよいようだから。なので、問題数で進捗管理することにする。進捗管理表を時間があるときに作成する。

  • 凡例 赤:やらなかった。黄:やったけど有意に進まず。青:やって進んだ。

のろのろ。

【DBiD】5 リレーショナル代数 (その3)


** 5.3 SQL式の評価
- えっと、この節は、SQLの意味をTutorial D (または
リレーショナル代数)が与えている、ということを言
いたいようだ。
- 違う言いかたをすると、SQLは実装により過ぎている、
ということかな。

** 5.4 拡張と要約
- 拡張と要約は、数値の加算などをリレーショナル代
数にて実施するための仕組み。
- 拡張はタプルどうしの計算をサポートする。
- 要約は「下位の属性」の計算をサポートする。

*** 5.4.1 拡張
- 構文
EXTEND <関係> ADD ( <表現> AS <属性名> )
- 例
EXTEND P ADD ( WEIGHT * 454 AS GMMT )
- 意味
Pに属性を追加した関係を表す。追加される属性の属
性名はGMMT、属性の型と値はWEIGHT * 454の型と値。
表現としてどういう語彙と構文が許されているかは
本書のここには記述されていない。

*** 5.4.2 要約
- 構文
SUMMARISE <関係1> PER (<関係2>)
ADD ( <要約表現> AS <属性名> )
- 例
SUMMARISE SP PER ( S { SNO } ) ADD ( COUNT ( ) AS P_COUNT )
- 意味
みてのとおり。すいません、言葉にするのが結構煩
雑なので割愛。

** 5.5 グループ化とグループ解除
- RVAについて、さわりだけ。
- 既存の関係からRVAを作る。
R1 GROUP ( { PNO } AS PNO_REL )
- RVAな関係をばらす。次の例ではR1が得られる。
R4 UNGROUP ( PNO_REL )


こつこつ。

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文について自分なりに整理しなおすことにする。


こつこつ。

本日の基礎トレ


  • 微積分 :Calculus
    (15/596)
    ※問題のうち、*と**はやらない。

  • 線形代数:線型代数
    (28/333)

  • 位相空間:はじめよう位相空間
    (9/182)

  • 計算練習:コンピュータの数学
    (2問)
    ※これはページ数による進捗管理が適さないことがわかった。問題にどんどん取り組んで、それに解答できるように本文を理解していく、という問題駆動がよいようだから。なので、問題数で進捗管理することにする。進捗管理表を時間があるときに作成する。

  • 凡例 赤:やらなかった。黄:やったけど有意に進まず。青:やって進んだ。

のろのろ。

【DBiD】5 リレーショナル代数 (その2)


** 5.2 オリジナルの演算子
- この節では、Coddが最初に定義したリレーショナル
演算子を概観する。

*** 5.2.1 制限
- 構文
<関係> WHERE <ブール式>
- 例
S WHERE CITY = 'Paris'
- 意味
ブール式が真となるタプルのみを含む関係。
*** 5.2.2 射影
- 構文
<関係> { <属性1>, <属性2>, ... }
<関係> { ALL BUT <属性1>, <属性2>, ... }
- 例
S { SNAME, CITY, STATUS }
S { ALL BUT SNO }
- 意味
指定された属性だけを含む関係。ALL BUTのとき
は、指定されていない属性だけを含む、となる。
*** 5.2.3 結合
- 構文
<関係1> JOIN <関係2>
- 例
P JOIN S
- 意味
見出しは、関係1と関係2の見出しの和集合とする。
和の際の重複としたくない見出しについてはさきんじ
てRENAMEしておくものとする。重複している見出
しについて、値が等しいタプルを両関係からピッ
クアップしてそれを属性に重複が無いように結合
したものにて本体を成す。
*** 5.2.4 交わり
- 構文
<関係1> INTERSECT <関係2>
- 例
S { CITY } INTERSECT P { CITY }
- 意味
同じ型の関係1と関係2について、両者で重複する
タプルを本体とした関係。結合で、関係1と関係2
が同じ型のときと同じふるまい。
*** 5.2.5 和
- 構文
<関係1> UNION <関係2>
- 例
S { CITY } UNION P { CITY }
- 意味
同じ型の関係1と関係2について、関係1に含まれ
るタプルも関係2に含まれるタプルも、両方とも
含めた本体をもつ関係。
*** 5.2.6 差
- 構文
<関係1> MINUS <関係2>
- 例
S { CITY } MINUS P { CITY }
- 意味
同じ型の関係1と関係2について、関係1の本体か
ら、関係2に含まれるタプルは除外したものを本
体にもつ関係。
*** 5.2.7 デカルト積
- デカルト積はCoddのオリジナルには含まれていな
いようだ。
- Tutorial Dにも含まれていない。
*** 5.2.8 商
- Dateは商が嫌みたいで、記述が投げやりなので、
割愛。
- リレーショナル比較という別の演算子にて、同じ
効果がより簡単に得られる、というのが、Dateが
やる気がない理由のようだ。
*** 5.2.9 プリミティブ演算子
- プリミティブ演算子というのは、それらがあれば、
他の演算子も表現できる、というようなミニマム
セットのことである。
- ここでのプリミティブ演算子は、制限、射影、結
合、和、半差、である。


こつこつ。

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月27日月曜日

【DBiD】5 リレーショナル代数


* 5 リレーショナル代数

自分なりの言葉で書く

- リレーショナル代数の演算の特徴
- 閉包である。
- 非破壊的である。
- 関係変数は普通の意味での変数である。
- つまり、普通の代数ってことだろうな。
- こういうことを強調せざるを得ないのは、SQLがそう
じゃないから、と予測する。

- Tutorial D の設計について

- unionやjoinのように、オペランドの属性どうしが一
致しなければならない演算においては、該当属性は
型と属性名が一致していることを求める。例えば、

P JOIN S

としたとき、PとSにそのような属性があることをユー
ザが気をつけなければいけない。

- SQLにあるようなドット表記の名前は禁止。

** 5.1 閉包

- 閉包である、ということは、リレーショナル代数演
算にて演算子が連なるとき、それぞれの入出力が関
係であるということであった。
- しかしこれは概念上のことであり、実際の処理にお
いては、効率のために、処理系はなるべく中間の関
係を実体化しないように工夫するであろう。
- 閉包ということは、関係が持つ見出しの推論と関連が
ある。
- Tutorial Dにて、

---

(P JOIN S)
WHERE PNAME > SNAME

---

- という文を考えると、PNAME > SNAMEというのが問わ
れているのは、PでもSでもなく、(P JOIN S)が返す
関係だ。なので(P JOIN S)の見出しがなんなのかがP
とSから特定されねばならない。これが見出しの推論
である。
- 具体的には、そのJOINによって作られる集合の見出
しは、Pの見出しとSの見出しの和集合になる。

- Tutorial Dでは、代数演算において属性名が役割り
を果たすので、属性名の書き換えは重要である。そ
れはRENAMEで実施する。

S RENAME (CITY AS SCITY)


こつこつ。

本日の基礎トレ


  • 微積分 :Calculus (15/596)
    ※問題のうち、*と**はやらない。
  • 線形代数:線型代数 (27/333)
  • 位相空間:はじめよう位相空間 (9/182)
  • 計算練習:コンピュータの数学 (29/461)
    ※これはページ数による進捗管理が適さないことがわかった。問題にどんどん取り組んで、それに解答できるように本文を理解していく、という問題駆動がよいようだから。なので、問題数で進捗管理することにする。進捗管理表を時間があるときに作成する。

  • 凡例 赤:やらなかった。黄:やったけど有意に進まず。青:やって進んだ。



のろのろ。

【基礎トレ】基礎トレもエントリに

基礎トレがどうしてもなおざりになってしまう。
そこで、基礎トレもエントリとして上げることにして発奮材料にしよう。

括弧の中は、ページ数での進捗状況。

この4つをやることはとても重要。知識として身に付けるのが目標ではなく、体で覚えることが目標。ゆっくりやる。これらが身体化できれば、いろいろ自由自在になれるはず。これらを終えれば、現在のレベルを、高校三年生をすっとばして大学一年生としてもよいはずだ!

のろのろ。

【雑】ブログのラベル(タグ)整理

ラベル(タグ)のメンテをちょこちょこやってます。
モチベーションは次のとおり。

  • 話題がクロスオーバーしてきたので、タグを整備すると自分にとっても便利。
  • 一過性の興味などにより、エントリが1つしかないタグがある。これは他のにマージしていく。タグ数を減らした方が見易いから。
  • 同義語なタグについて考える。そのまま残すことに語彙として価値があるか、それともマージするか。


こつこつ。

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月25日土曜日

【DBiD】4 関係変数


* 4 Relation Variables

この章、私にとってはけっこう難しい、というかDateが
結局何を言いたいのかが、訳書でも原書でも、すっと入っ
てこない。そこで、この章では、原書をベースにしつつ
訳書も参照するという二段がまえでいく。

例によって、このエントリは、読書メモよりも私的まと
めに近い。


- まずベース例をTutorial Dで記述する。

---
var S base relation
{ sno sno, sname name, status integer, city char }
key { sno };

var P base relation
{ pno pno, pname name, color color, weight weight, city char }
key { pno };

var SP base relation
{ sno sno, pno pno, qty qty }
key { sno, pno }

foreign key { sno } references S
foreign key { pno } references P;
---


** Updating Is Set-at-a-Time
- 一般のプログラミング言語と同じように、変数と値
を考えよ、ということ。
- insert, delete, update の説明がある。どうやら、
これらは非破壊的なようだ。
- すなわち、関係、タプルといったものは、それらに
演算子が作用すると結果としての関係やタプルが生
成される。そしてその結果を関係変数に代入するな
らば、関係変数が参照する値は更新されたことにな
る、と。

** More on Candidate Keys
- Candidate Keysの定義。原文まま引用。

---
Definition: Let K be a subset of the heading of
relvar R. Then K is a candidate key (or just key
for short) for R if and only if it posesses both
of the following properties:

Uniqueness
No possible value for R contains two distinct
tuples with the same value for K.

Irreducibility
No proper subset of K has the uniqueness property.
---

- ふむ。シンプル。

- 注意点をいくつか。
- キーが設定されるのは、関係ではなく、関係変数
である。これはおどろいた。理由としては、キー
を設定するということは、なにがしかの制約をか
けるということだが、制約は変数に所属すべきだ
から。なぜかというと、制約というのは何かを更
新するときに機能するが、更新されるのは値では
なく変数が何を参照するか、だから。納得!
- これがCommon Lispや他のプログラミング言語に
あるかどうか考えてみる。変数の型、はある意
味制約をかけている。Object指向のObjectなら
ば、実装としてそういう制約をつくることはで
きるといえばできる。
- キーの値となるのは、属性そのものではなく、その
属性のみをもつタプルである。今までの諸定義から
すればあたりまえのことだが、これも言われないと
意識されないことだなぁ。
- functional dependency (関数従属性)について。
自分なりにちゃんと書いてみる。

関係変数Rvが、値として関係Rをもち、キーとして
Kが設定されているとする。すると、関係Rに含まれ
るタプル値一般をTとあらわすとき、Tは次の二つの
タプルを含むと見ることが可能であり、それは、K
を見出しとして持つタプル(Tkと呼ぶ)と、Kに含ま
れない属性を見出しに持つタプル(Taと呼ぶ)である。
これら2つは属性に重なりはない。

さて、(a)関係Rに含まれるタプルについてTkとTaの
対応を写像ととらえることができて、それは、
(b)Tkの集合とTaの集合の間の写像であり、全射で
ある。

(a)(b)が成り立つ理由は、関係Rに含まれるタプル
にそもそも重複が無く、かつ、キーの値となるタ
プル達にキーの定義から重複が無いから。

** More on Foreign Keys
- 定義なので原文まま引用。

---

Definition: Let R1 and R2 be relvars, not
necessarily distinct, and let K be a key for
R1. Let FK be a subset of the heading of R2 that,
possibly after some attribute renaming, involeves
exactly the same attributes as K. Then FK is a
foreign key if and only if, at all times, every
tuple in R2 has an FK value that is equal to the K
value in some (necessarily unique) tuple in R1 at
the time in question.

---

- 外部キーというのは実践にて頻繁に使うので強調さ
れることが多いが、理論の立場から言えば、制約と
いうより多きな概念における例のひとつにすぎない。

** More on Views

- 定義なので原文まま引用。

---

Definition: A view or virtual V is a relvar whose
value at time t is the result of evaluating a
certain relational expression at that time t. The
expression in question is specified when V is
defined and must menthion at least one relvar.

---

- リレーショナルモデルにおいては、base relvarであ
るかvirtual relvarであるかということは、どちらを
先に定義して、どちらをそれを使った表現で定義する
かという違いだけであり、演算子における扱いや制約
の設定など、その使用方法(原文ではlook and feel)
にほぼ違いはない。これを

The Principle of Interchangeability (of base
and virtual relvars) [訳:交換可能性の原理]

という。

- SQLは、この原理のサポートが弱い。以下はその例。
- テーブルのrow IDに関すること。これがあると、
rowIDというのはbase relvarにしか存在しないはず
だから、原理から逸脱している。
- entity integrity(主キーの要素はnullではいけな
い)という制約も、base relvarに対する言明なの
で、これも原理から逸脱している。ただし、これ
はそもそもnullの存在をDateは否定しているので、
その観点でも却下なのだが。
- viewのupdateに関する機能が弱い。

- なお、viewのupdateについては、まだ論争が絶えな
い状態。Dateの見解の詳細は、The Third
Manifesto, Third Editionを参照のこと。

- relcon(関係定数)の紹介。

- snapshotの紹介。

** Relvars and Predicates

この節が一番もやもやするので、自分で完全にまとめ直
す。

- 関係に含まれるタプルは、それぞれ論理学の命題で
あると考えてみる。
- すると、関係は論理学における知識ベースに位置付
けられる。
- 関係に含まれるタプルは、全て真の命題である、と
言っても諸事情は整合する。
- この文脈にて、リレーショナルモデルでは、閉世界仮
説を採用している。すなわち、知識ベースに無い命
題は偽とする。
- 例えば、関係「商品」があって、その見出しに「商
品名」、「種類」、「在庫数」があるとすると、
タプル、

{商品名 あわあわ, 種類 石鹸, 在庫数 5}

は、商品名がキーであるとすると、

商品名あわあわは、種類が石鹸であり、在庫数が5で
ある。

という命題であり、これは真であるということだ。
- この文脈では、属性は自由変項をひとつ含んだ言明で
あり、その変項の領域が本体のタプル達が含む該当
属性の値になる。
- 属性A1,...,Anの言明版を、A1(X1),...A1(Xn)とする
と、その関係を参照している関係変数は、

A1(X1)^...^A1(Xn)

という言明を取扱っている、と言える。本体には、
これが真となるX1,...,Xnが全て格納されており、こ
こに格納されていないX1,...,Xnについては閉世界仮
説により全て偽となるからだ。
- ということは、関係変数は、ある言明(論理式といっ
てもよい)についての真偽を司っているものであり、
論理学でいうところの述語の定義の役割を果たして
いる。

- ここで私が「述語の定義の役割を果たしている」と書
いたのは、Dateの「関係変数の見出しは述語である」
というのと違っている。というのは、私はここで論理
学における意味で述語をつかっているからだ。そこで
は、述語は写像であり、論理式の中で、p(X,Y)や、
p(a,b)などと項を引数にとりつつ使われるものだから
だ。上の流れの説明においては、関係変数が参照して
いる関係は述語を定義していると言えるが、それ自体
が述語として運用される構文は提示されていない。

- ただし、Dateのrelvar predicate (関係変数述語)の
くだりは、私の組み立てと一致している。「関係変数
の見出しは述語である」というのはアジテーション
なだけなのかもしれない。

- さて、このように関係や関係変数を論理学の観点で
捉えるということは、リレーショナル式(relational
expression)によって表現されている関係についても
適用できる。

** More on Relations Versus Types
- Dateは、リレーショナルモデルは形式理論であり、
上で述べたように論理を取り扱うものだと言う。で
あるならば、形式理論として統語論と意味論を書き
くだしてもらった方がやっぱりわかりやすいなぁ。
- ちょっと説明が回りくどい気がするが、リレーショナ
ルモデルの型は、いわゆる形式理論の型である、とい
うことが言いたいようだ。

** Summary
- 特になし。


こつこつ。

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月23日木曜日

【DBiD】3 タプルと関係


* 3 タプルと関係

** 私の雑感
この本はDateのアジというか、ノイズが多い。
このアジは、SQLをリレーショナルモデルと思い込んで
いる人に対する気付け薬的なものだろう。

そういう思い込みが無い人にとっては、アジはいいから、
もうちょっとすっきり整理して言いたいことを言って欲
しいなぁ、と感じさせるものではないか。実際私はそう
だ。しかしそれはこの本を読んでいる私の選択の問題だ
ろう。C.J.Dateは著書が豊富なので、その中にはすっき
り整理してある本もあるのだろう。

また、この本の訳書のタイトルはまずいかもしれない。
「データベース実践講義」というタイトルで期待するこ
とは、本書の内容とは違うことが多いのではないか。原
書の「Database in Depth」はそういう意味ではアリであ
る。訳書のタイトルのアンマッチが、読者の誤解や不評
に繋らなければよいのだが。私自身は原題の認識が先行
していたので、アジ以外は期待通り。

閑話休題。

という事情も加味しつつ、この章も自分なりのまとめを
書く。読書メモとはちょっと違うものです。


** タプルの定義
定義なので、原文まま引用。

---
T1,T2,...Tn (n>=0)が型名であり、それらが必ずしも異
なるとは限らないとする各Tiに識別可能な属性名Aiを関
連付ける。これによって生じるn個の属性名と型名の組
みは、それぞれ属性である。各属性をTi型の値viに関連
付ける。それによって生じるn個の属性と値の組みは、
それぞれコンポーネントである。そのように定義された
n個のコンポーネントからなる集合(t)は、属性
A1,A2,...,Anのタプル値(または略してタプル)である。
値nはtの次数であり、次数1のタプルは単項、次数2のタ
プルは2項、次数3のタプルは3項である。一般に、次数n
のタプルはn項である。n個の属性からなる集合は、tの
見出しである。
---

** タプルをCommon Lispのオブジェクトで表現してみる

- 型名
- これはatom。

T1 T2 T3

- 属性名
- これもatom。

A1 A2 A3

- 属性
- これはdotted pairにしてみる。

(T1 . A1)
(T2 . A2)
(T3 . A3)

- 値
- これもatomにしてみる。

v1 v2 v3

- コンポーネント
- dotted pair。

((T1 . A1) . v1)
((T2 . A2) . v2)
((T3 . A3) . v3)

- タプル値 (タプル)
- listで表現する。しかしタプル値としては集合な
ので、そこは表現しきれていない。

(((T1 . A1) . v1)
((T2 . A2) . v2)
((T3 . A3) . v3))

- 見出し

タプル値、

(((T1 . A1) . v1)
((T2 . A2) . v2)
((T3 . A3) . v3))

の見出しとは、

((T1 . A1)
(T2 . A2)
(T3 . A3))

である。listだが、集合として使うことを想定して
いる。

- タプル値というのは、super-boxedなデータみたいな
ものかな。型のみならず、現在の(DSLの意味での)
ドメインの名前(属性名)までもデータに入っている。
そうか、Common Lispとかの構造体と同じなのか。
例えば、HyperSpecから例をとると、構造体の定義は、

---
(defstruct ship
(x-position 0.0 :type short-float)
(y-position 0.0 :type short-float)
(x-velocity 0.0 :type short-float)
(y-velocity 0.0 :type short-float)
(mass *default-ship-mass* :type short-float :read-only t))
---

であり、一応生成された構造体のスロットも、自分
自身のスロット名やスロットの型を知っている。な
るほどなるほど。

** タプルに関するトピック

- nullを含むタプルは存在しない。
- そう決めるのは自由なのだが、Common Lispには
nilがあり、構造体の値にも使えたりする。

- タプルの部分集合はタプルである。
- 見出しの部分集合は見出しである。

- 次数がゼロのタプルを0タプルと呼ぶ。
Common Lisp的に表現すると、

()

かな。
- タプルの等価性は、Common Lispのequalp的に定義さ
れている。

** 関係の定義
定義なので原文まま引用。

---
{H}をタプルの見出しとし、t1,t2,...,tm (m >= 0)を見
出し{H}を持つ個々のタプルであるとする。{H}とタプル
の集合{t1,t2,...,tm}との組み合わせrは、属性
A1,A2,...,Anにおける関係値(または単に関係)である。
ここで、A1,A2,...,Anは{H}の属性である。rの見出しは
{H}である。rは見出しと同じ属性(よって、同じ属性名
と型)と、見出しと同じ次数を持つ。rの本体はタプルの
集合{t1,t2,...,tm}である。値mはrの濃度である。
---

- タプルの流れで、Common Lispで関係を表現すると、

まず、これが見出しで、

((T1 . A1)
(T2 . A2)
(T3 . A3))

タプル値が例えば、3つあるとするとそれらは、

(((T1 . A1) . v11)
((T2 . A2) . v12)
((T3 . A3) . v1))

(((T1 . A1) . v21)
((T2 . A2) . v22)
((T3 . A3) . v23))

(((T1 . A1) . v21)
((T2 . A2) . v22)
((T3 . A3) . v23))

なんぞであり、タプル値の集合が関係の本体なので、

((((T1 . A1) . v11)
((T2 . A2) . v12)
((T3 . A3) . v1))
(((T1 . A1) . v21)
((T2 . A2) . v22)
((T3 . A3) . v23))
(((T1 . A1) . v21)
((T2 . A2) . v22)
((T3 . A3) . v23)))

リストで集合を表現するとこれが本体。

この本体と見出しを組み合わせたのが関係だから、
それをリストであらわすと、

(((T1 . A1)
(T2 . A2)
(T3 . A3))

((((T1 . A1) . v11)
((T2 . A2) . v12)
((T3 . A3) . v1))
(((T1 . A1) . v21)
((T2 . A2) . v22)
((T3 . A3) . v23))
(((T1 . A1) . v21)
((T2 . A2) . v22)
((T3 . A3) . v23))))

これが関係。

** 関係に関するトピック
- 本体の部分集合はすべて本体である。
- 関係の中でのタプルの重複はリレーショナルモデル
では禁止されるべきである。Tutorial Dでは禁止さ
れている。SQLでは禁止されていない。

** nullを禁止すべき理由
- リレーショナルモデルは、2値論理(2VL)に基づくべ
きである。(その方が有用だから) そして実際に、リ
レーショナルモデルの中の各部は2値論理に基づいて
組みたてられている。
- nullを含むということは、述語の値が
true,false,unknownの3値になり3値論理(3VL)という
ことになる。
- 2値論理の機構と3値論理の機構が混在すると、期待
する正しい結果が得られないというか、保証されな
い場合がでてくる。実際、SQLではそういった例があ
る。
- よってnullはリレーショナルモデルに含まない方が
よい。
- nullが入っている状態はリレーショナルモデル以外
の何かであると認識した方がよい。

** TABLE_DUM と TABLE_DEE
- TABLE_DUMは、空の関係である。
Common Lispの表現の流れでは、

(() ())

である。次数ゼロなので、見出しは空集合である。ま
た、本体も何も含まないので、空集合である。

- TABLE_DEEは、次数ゼロで空のタプルを壱つ含む関係
である。
Common Lispの流れの表現では、

(() (()))

である。本体に空のタプルを壱つ含んでいるが、空
のタプルは空集合なので、このようになる。

- これらはリレーショナル代数において役割をもつ。
TABLE_DEEはゼロの役割を果す。
- 真理値の観点で言うと、TABLE_DUMはNO/FALSEの役割
を果たし、TABLE_DEEはYES/TRUEの役割を果たす。


こつこつ。

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月21日火曜日

【DBiD】2 関係と型


* 2 関係と型
自分なりのポイントを自分なりの言葉で書く。

- まず、基本的には、リレーショナルモデルにもいわ
ゆる型がありますよ、ということ。

** Coddのオリジナルモデルからの修正
- Coddがドメインと呼んでいるものは型にすぎない
- Coddは、異なる型に属する属性間の比較を許してい
る(ドメインチェックオーバーライド)が、これは禁
止されるべきである。
- データの「原始性」という言葉にはちゃんとした意
味はない。
- 何が「原始的」かは、ユーザの観点というかニー
ズによる。

** リレーショナルモデルの型システム
- 型
- = 値の名前付き集合
- リレーショナルモデルの型システムの特色/注意点
- 強い型付けである。
- 本書ではすべての値は単独の型にのみ属するもの
とする。リレーショナルモデルの型継承及び型多
重継承については割愛する。(そんなものあるの
か?)
- すべての式は型をもつ。
- リレーショナルデータベースに含まれる変数は
関係変数のみである。他の変数は存在しない。
- 再帰的な型の定義を許さない。すなわち、関係r
の型がTであるとき、関係rの属性の型がTである
ことは許されない。
- ポインタ型は存在しない。この部分、記述が弱く
て正確には理解できないが、おそらくCのポイン
タのイメージだろう。メモリアドレスを取り扱
うような型ということかな。
- 型はスカラーと非スカラーに大別される。
- 非スカラー型
- = タプル型または関係型のこと。
- スカラー型
- = スカラー型以外の型。
- 属性へのアクセスはセレクタで行う。セレクタ
は例えばSNO('S1')など。
- 属性として関係も使える。これを関係値属性
(Relation-Valued Attributes)と言う。SQLでは
サポートされていない。


こつこつ。

2009年7月20日月曜日

【DBiD】1 概要

自分なりのポイントを自分なりの言葉で書く。


* 1 概要
- データベースの基礎の大部分はリレーショナルモデ
ルというものに属している。
- SQLはリレーショナルモデルではない。
- この本ではリレーショナルモデルを正しい用語
で正しく取り扱う。
- リレーショナルモデルの定義は徐々に変わりうるも
のである。(数学が進化するのと同じ意味で)
- この章ではE.F.Coddが提示したオリジナルモデルを紹介
する。後の章ではそれを発展させることもある。
- オリジナルモデルは、構造、整合性、操作の3つの基
本要素によって構成される。
- 構造の語彙
- 型 (ドメインとも)
- 関係
- 属性
- タプル
- キー
- 候補キー
- 主キー
- 外部キー
- 参照
- 整合性の語彙
- 整合性制約 (制約とも)
- 個々のDBに特有の制約
- 汎用的な制約
- 実体整合性
- null (Dateはnullの存在に批判的)
- 参照整合性
- 操作の語彙
リレーショナルモデルの操作は、リレーショナル代
数とリレーショナル代入から成る。
- リレーショナル代数
- 閉包性
- ネストしたリレーショナル式
- 最初に定義された8つの演算子
- 制限
- 射影
- 積
- 交わり
- 和
- 差
- 結合
- 商
- リレーショナル代入
- リレーショナル計算
- リレーショナル代数の代替物。
- 本書ではメインには扱わない。
- 本書の各所説明にてベースとなる例
- サプライヤと部品のデータベース
- 関係S
- 契約を結んでいるサプライヤを表す。
- 属性
- サプライヤ番号 (SNO)
- 名前 (SNAME)
- 評価または状態値 (STATUS)
- 所在地 (CITY)
- キー
- サプライヤ番号は主キーである。
- 関係P
- 部品の種類を表す。
- 属性
- 部品番号 (PNO)
- 部品名 (PNAME)
- 色 (COLOR)
- 重量 (WEIGHT)
- その部品の補完場所 (CITY)
- キー
- 部品番号は主キーである。
- 関係SP
- 出荷(出荷された部品とその部品を出荷したサ
プライヤ)を表す。
- 属性
- サプライヤ番号 (SNO)
- 部品番号 (PNO)
- 数量 (QTY)
- キー
- {SNO,PNO}は主キーである。
- この例では特定のサプライヤが特定の部
品を出荷できるのは1度まで、としている。
- データモデルの2つの意味
- 2つの意味の定義
1. リレーショナルモデルのこと。すなわち、リレー
ショナルモデルの3要素(構造、制約、操作)を抽
象機械を使って定義したもの。
2. 特定企業等の永続データのモデル。
- 本書では1の意味でデータモデルを用いる。
- 1の意味のモデルは、実装との分離を目的としたも
のである。これをデータ独立性と言う。
- 関係の語彙のチューンナップ
- 関係は見出しと本体とから構成される。
- 見出し
- = 属性の集合
- 次数/項数 (degree/arity)
- = 見出しに含まれる属性の数
- 本体
- = タプルの集合
- 濃度 (cardinality)
- = 本体に含まれるタプルの数
- 関係は常に第一正規形(1NF)である。
- 属性とタプルを指定する組は常にユニークであ
るということ。まあ、属性とタプルが集合なら
自然とそうであろう。
- リレーショナル代数の入出力がらみ
- リレーショナル代数によって関係から関係を作る
とき、素材になった関係を基底関係、作られた関
係を派生関係と呼ぶ。
- 派生関係にも名前をつけることができる。そのと
きそれをビューと呼んだり仮想関係と呼んだりす
ることもある。
- 関係と関係変数
- 関係はファーストクラスであり、名前をつけるこ
とができる。
- 語彙
- 関係変数 (テーブル変数とも)
- ソース式 (Tutorial Dの代入文の右辺のこと)
- ターゲット変数 (Tutorial Dの代入文の左辺のこと)
- 関係値
- relvar (関係変数の表記)

C.J.Date、ちょっとアジりすぎかも?
でも内容はおもしろそう。

こつこつ

2009年7月19日日曜日

データベース実践講義(Database in depth)を読む

Prologと論理のことが多少わかってきたところで、じゃあRDBって何なのさ、ということを探ってみたい。ぼやぼやーとした感じでよいので。

そこで、次の本を読むことにした。

C.J.Dateのデータベース実践講義

根を詰めると倒れるので、ぼやぼやーといきたい。

【検証論】3 形式的理論

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

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


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

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


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

こつこつ。

2009年7月17日金曜日

端末で論理記号がずれる

SKKの▽とかもそうなので、悩みは深いのですが、
端末で論理記号がずれる、というか、論理記号の後続が
めりこんじゃうんだよね。見ずらくて、萎える。

これ、端末の問題なのかフォントの問題なのかその両方
の組み合わせなのか、なんだけど、gtkアプリはずれない。

困ったなぁ。

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をかじったところ、論理について少し見通しがでてきた。

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

本はこれ。

プログラム検証論

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

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

【AIMAメモ】Agentアプローチ <=> Domain指向 の間違い

------
Agent in Environment.

なんですがこれは、

Domain in World.

と同型であり、ここでDomain指向との対応がとれる、と。
------

違う! これは同型ではない。同型なのは、

------
an Agent in an Environment in the World
an IT system in a Domain in the World
------

だ。

こんなんじゃ、駄目だ。。。

2009年7月13日月曜日

【AIMAメモ】PrologとLisp

論理プログラミングをやろうと思ったら、Prologはひとつの選択肢だろう。

Prologの処理系を使うというのもあるが、別の言語をメインで使っていて、一部論理プログラミングを使いたいとする。

そうするとそのホスト言語でProlog的なものを実装するわけだが、そのとき、

  • 実装が楽であり、
  • 実装したものを使う際にホスト言語と似ていて使いやすい

ということが大事だろう。すると例えばCとCommon LispをくらべるとCommon Lispの方が適していると思う。

ではRubyだとどうだろう?
結構いけそうな気がする。しかし、記号(Symbol)の取扱いがCommon Lispの方が統一的かつ簡易なので、Common Lispの方が楽だろう。(Rubyはあまりくわしくないので間違いかも)

PrologとLispのつながりというのはこの程度じゃないかなぁ。

もしかしたら、もっとあるのかもしれないが、今のイメージはこんな感じ。


とりあえず、これにて、今回の「AIMAかじり」は終了しよう。
AIMAは別の機会にがっつりやりたい。

次は、今回習得したPrologとAIMAの知識を利用して、PAIPのProlog実装とその利用をちゃんと理解するステップに入ろう。

【AIMAメモ】Algorithm = Logic + Control の周辺

Algorithm = Logic + Control.

なわけですが、一方で、より有名なので、

Programs = Data structures + Algorithms.

があるわけです。

ちなみにAIMAがエージェントアプローチと呼ばれるのは、AIMAで取扱うものは、機械だろうが生物だろうが、ソフトウエアだろうがハードウエアだろうが、Common Lispが採用言語だろうがJavaがそうだろうが、エージェントという統一的な観点で整理しているからです。

そこで、Logicが知識表現である、というのが私にとっては大きな気づきでした。AIMAの中では他の知識表現として統計的なものを含めてLogic以外のものも取り上げられています。ベイズとか隠れマルコフとか。それらがどちらかというと現代的なAIのお話になっている。

さて、日頃プログラムを書くときにデータというのはよく使うわけですが、これもエージェント的な観点でみると何かしらの知識表現とも見做せてきます。そうすると、

Algorithm = Logic + Control.

ではなく、

Algorithm = Knowledge Base + Control.

の方がいいように思えてきます。Knowledge Baseの構築方法の一つとして知識表現にLogicを使うこともあるよ、ということで。Knowledge Baseを拡大解釈すれば、あながち間違いではないかと。

するとデータベースってなんじゃないな、ということが気になるわけです。

これはこれで、Prologと、SQL(というか関係代数)との関係含めて先々確認しなければいけないのですが、ある種のデータベースはKnowledge Baseとみなすのがよいと思うし、ある種のデータベースは、外界としてしまってデータベースとのやりとりは、エージェントのセンサを介して情報を得るという、外部入出力とみなすのがよいように思います。直感ですが。



まとめると、Environmentの中で、

Agent = Sensor + Actuator + Intelligence.

なんですが、Intelligence というのはいろいろありえてSoftwareの場合もあり、
Sensor,Actuator,Intelligenceの全部がSoftwareの場合がよくあるプログラミングでやっていることで、
だからそれをProgramと呼んで、
その場合は全部Softwareなので、どこでインターフェイスを切りますかということが整理の入口になりそれがアーキテクチャであり、
同じ対象領域でも何がSensorで何がActuatorでとかは違うわけで、
SensorとActuatorは外部インターフェイスというか入出力と考える部分にあたり、
するとIntelligenceの部分が入出力以外ということになり、いわゆるProgramの本体部分なので、

Intelligence = Data structures + Algorithm

なんですが、Data structuresを知識表現とみれば、

Algorithm = Knowledge Base + Control

のKBに吸収されてしまうので、

Intelligence = Knowledge Base + Control

となるなか、

データベースはEnvironmentに属すのかIntelligenceに属するのかという判断があるので、
その判断によって、EnvironmentにいったりKBにいったりするという。

さて、大本にもどると、

Agent in Environment.

なんですがこれは、

Domain in World.

と同型であり、ここでDomain指向との対応がとれる、と。
そちらの言葉で言えば、DomainとWorldの境界線がSystem Boundaryにてシステム思考が出てくる、と。

また、Common Lispのhomoiconicというのは、

Algorithm = Knowledge Base + Control.

ここのKBとControlの境目を柔軟にして探検的にプログラミングできますよ、ということで、それだけじゃなくて、リストまたはS式というのは知識表現言語として柔軟ですよ、というつながり。

つながった?

【AIMAメモ】FOPLの確定節(definite clauses)

まず、訳語の揺れについて。
第七章の命題論理では、definite clausesを確定節としているが、一階述語論理の第九章では限定詞節としている。よくわかんなくなっちゃったので、原書を確認した。ま、このくらいはしょうがないのかな。

で、一階述語論理(FOPL:FOPLはFOLとほぼ同義)にもホーン節的なものは存在しているのだ(AIMAではFOPLの方はホーン節と呼ばない)。
ここではホーン節と呼んじゃおう。

ホーン節は正リテラルをゼロ個または一つ含む。一つ含む方をdefinite clausesと呼ぶ。またFOPLの場合の違いは、全称限量子が略記されていると見做す。これがPrologの文だ。

hoge(X) :- piyo(X),poyo(X).

というわけで、PrologのKBはホーン節の選言文となる。すなわちFOPLよりは記述力が弱い。そのかわりに、推論のスピードを確保している。ホーン節も記述力はナカナカなので、落としどころ、という感じか。

詳細はまだつかめていないが、FOPL(FOL)とPrologの関係はイメージできるようになった。

【AIMAメモ】融合規則からホーン節へ

で、融合規則(resolution rule)なる推論規則が注目される。これは、命題論理においては、この推論規則たったひとつで完全である。すなわち、KBから伴意される任意の文を導出できる。モーダスポーネンスもなんもかんもいらないのだ。

ここで、命題論理における任意の文がk-CNFの形で書けることが重要な役割をもっていることになる。するとKBも、任意の文αもk-CNFだから、融合法を適用できる。

この文脈でホーン節、登場。

融合法(= 融合規則+探索)は強力だが、そのままで使うのではなく、文に含まれる節の形を多少制限するといろいろメリットがある。それがホーン節。

ホーン節は正リテラルを高々ひとつ含む選言節である。

(¬A∨¬B∨C)はホーン節だが、(¬A∨B∨C)はホーン節ではない。ホーン節は含意に変形できる。例えば、

(¬A∨¬B∨C) は (A∧B)⇒C、

とか。ここで(A∧B)の部分を体部(body)と呼び、Cの部分を頭部(head)と呼ぶ。

ここでPrologと繼がった! Prologの記法だと、

C := A,B.

であり、左右が逆だが意味は同じ。

head := body.

なので用語も同じ。

ただしここでの話は命題論理なので、FOLとの関係はどうなっているのというのはわからない。まだ関連が見えただけ。

【AIMAメモ】推論規則(推論パターン)

命題論理のお話。

統語論を決める。
意味論にて、モデルの考え方を決める。ここでは、命題記号に直接真偽を割り当てるのがモデルとし、結合子の意味論は真理値表にて定義することにし、定義する。

すると、伴意の考え、および論理的同値の考えから、命題論理の複合文についての論理的同値関係がいろいろでてくる。ドモルガンの法則と呼ばれるものだとか、なんやかんや。

ここまでは命題論理の定義(= 統語論 + 意味論)からストレートな感じである。

で、推論規則(推論パターン)。

ここ、AIMAではヒューリスティックな流れだ。モーダスポーネンスとかAnd除去とかをどうやって導出するのか、もしくは何を推論規則と認定するかは曖昧である。例えば、And除去は論理的同値だが、モーダスポーネンスは違う。

ただ、何を推論規則とするかには何か法則性があるんだろうな、と感じる。

推論規則は証明に使えてナンボだと思うので、おそらくその観点での判断になるのかな。

また、推論規則を定めるまでは統語論と意味論が混ざっているが、推論規則を定めると、それは文の変形(書換え)のみになり、統語論だけで処理が進む。

伴意による推論アルゴリズムはモデルチェックであり、意味論ごりごりなわけだが、推論規則による証明という推論アルゴリズムは、統語論ごりごりであるという対比があるように思う。

【AIMAメモ】論理(logic)の誤解の誤解

http://aka-cs-blog.blogspot.com/2009/07/aimalogic.html
で書いた、
---
これでは計算機科学的には間違っていて、

知識(論理による表現) <-(推論規則)- アプリケーション(探索実装)

なのだ。
---
というのはちょっとどうかと思えてきました。融合法(resolution)のみを考えているわけではないので。

---
知識(論理による表現) <-(推論アルゴリズム)- アプリケーション(実装)
---

の方がいいかも。

これも気づき。

2009年7月12日日曜日

【AIMAメモ】数理論理学の三階層 (または論理という言葉の曖昧さについて)

論理(logic)という言葉が、一般的にも、論理学においてもかなり曖昧に運用されていることが理解できてきた。

これから書くことはAIMAに書かれていることではなく、AIMAに書かれていることを起点にして自分なりに考えたことだ。

まず数理論理学とはどんなものなのか多少探ってみよう。

  • 論理学と数理論理学との関係はどうなのだろう。
  • 考えてみると、そしていくつか調べてみると、大体次のようなイメージでよいのではないか。
  • 論理学の方が広い概念である。
  • 数理論理学は論理学の一分野である。
  • 数理論理学では、記号を用いる。別名、記号論理学とも呼ばれる。
  • 記号は、音、物理形状、文字などいろいろな形を取りえるが、記号論理学で扱うのは文字と考えてよいだろう。
  • これは、計算理論における情報の定義に関わるが、あらゆる情報は文字で表現できる、もしくは文字で表現できることが情報の定義である、ということを背景としている。

さて、次にもともと論理学とは何だったのだろう。


  • もともとでいうと自然言語と知性に関する知的探求である。
  • 自然言語をつかってわれわれは情報を伝達したり、考えたり、意見を戦わせたりするのだが、どうやらそこには何か法則性というか何か構造があるようだ。
  • 自然言語の文について、その何か構造がありそうに思える部分に着目しよう。逆に言うと、それ以外の部分を除去して考えていこう。
  • その何か構造と思えるものを論理(logic)と呼ぼう。
  • 論理と名前つけたものは、どうやら人間における事実の言明や仮定や推論などの知的活動や知的能力の重要な部分ではあるまいか。
  • 言葉という「外部表現」から、人間の思考という「内部表現+推論」を探っていこう。

というようなものが論理学の原始的モチベーションなのではないか。もちろん学問分野の定義は曖昧なので、進めば進む程、定義や対象領域も変化していくのですが。

で、数理論理学というのは、次のとおり。

  • 別に自然言語に限らなくてもいいじゃん。
  • ひとつには自然言語って難しいよ。論理としておぼろげながら捉えられた構造の研究に集中したい。
  • 自然言語じゃなくて、論理研究用のミニ言語みたいなのをつくっちゃうのがいいじゃん。(形式言語)
  • その言語は文法(=統語論)もきっちり決めちゃおう。


ここまでは前置きです。で、数理論理学というのは、ある意味、どうやら概念として次の三階層をとっているように思えてきたというお話です。


  • 1. 数理論理学自体の枠組み
    2の数理論理フレームワークを俯瞰してみたときに共通していると考えられる概念。逆にいうと2のフレームワークを新しく考えるときに満たさなければいけない条件や、使わないければいけない語彙。
  • 2. 数理論理フレームワーク
    3の具体的な論理を作る際のフレームワーク。いろいろなものがあり、問題領域に対してどれを使って論理をつくろうか選択したりする。
  • 3. 具体的な問題解決のための数理論理
    例えば、算数(小学校で習う形態は数理論理フレームワークを使っていないが)であったりWumpus Worldのエージェントを構成する論理(命題論理という数理論理フレームワークを使用)だったり。


そして、数理論理学の諸概念は、この3つの階層に分かれている。代表的なものを列記しよう。


  • 1. 数理論理学自体の枠組み
    数理論理学で扱う「論理」は必ずこれらの概念下で構築されている。

    • 数理論理学は形式言語を対象とする。
    • 形式言語では統語論と意味論が定義されている。
    • 統語論はconstantsとvariablesを含む。
    • モデル:ある文について、それが含むvariablesがそれぞれconstantsに特定化されたものをモデル(別名、可能世界)と呼ぶ。
    • 真理値:文は、個々のモデルについて真または偽となる値をもつ。その値を真理値と呼ぶ(ファジ論理はここでは除外する)。文αがモデルmで真となることを、mはαを充足する、とも言う。
    • 伴意:2つの文αとβについて、αの真理値が真であるあらゆるモデルにおいてβの真理値が真となるとき、文αから文βが伴意される、という。α |= β と書く。
    • 知識ベース:文の集まりを知識ベースと呼ぶ。KBと略記する。
    • 推論:あるKBと伴意関係にある文αは存在するかもしれないし存在しないかもしれない。そんなαを推論アルゴリズムiがKBをもとに見付けることができる場合、「αはiによってKBから導出された」と言い、KB |-i αと書く。
    • 推論規則:個々の数理論理フレームワークにおいて、その統語論と意味論とから発生する文から文への変換ルールを推論規則という。
    • 証明:ある導出をするための推論規則の適用系列を証明と呼ぶ。
    • 融合法:完全な探索アルゴリズムと単一の推論規則とによって完全な推論アルゴリズムを生み出す方法。
    • 健全性:ある推論アルゴリズムが、それが導き出す文はKBと必ず伴意関係があることが保証されている場合、その推論アルゴリズムは健全である、という。また、真理値を保存する、という言い方もある。
    • 完全性:ある推論アルゴリズムが、KBと伴意関係があるαを全て導出可能なことが保証されている場合、その推論アルゴリズムは完全である、と言う。
    • 論理的同値性:二つの文αとβについて、各々が真となるモデルの集合が一致するとき、αとβは論理的に同値であるという。α <=> βと書く。(伴意を用いた別の定義もある点に注意)
    • 妥当性:ある文がすべてのモデルに対して真となるとき、その文は妥当であると言う。妥当な文のことをトートロジと呼ぶ。
    • 充足可能性:文αが真となるモデルmが存在するとき、文αは充足可能であると言う。
    • 単調性:非形式的に言うと、センサにあやまりがないことが保証されている場合で新しい知識たる文βが得られたとしても、KB |= αならばKB^β |= αである。すなわち、βを知る前に導出されていた文αがβの出現によってくつがえされることはない、ということ。

    などなど。
  • 2. 数理論理フレームワーク
    1の各種概念を用いているが具体的な問題領域には適用してはいないフレームワーク。例えば、命題論理、一階述語論理、高階述語論理などがこれにあたる。基本的には、それぞれの「論理」にて統語論や意味論やそれらを表現する語彙は異なる。もちろんそれぞれ発展していったものなので、その関連性から同じような用語が現れることもあるが、それは上の1の意味で共通な用語ではないことが要注意である。以下は命題論理の場合の語彙を示す。

    • 統語論の語彙:原子文、命題記号、複合文、論理結合子、リテラル、選言、連言、含意文、前提、結論、双条件文、ホーン節
    • 意味論の語彙:真理値表
    • 推論の語彙:モーダスポーネンス(三段論法)、And除去、演繹定理、背理法、連言標準形、前向き推論、後ろ向き推論、Davis-Patnumアルゴリズム

    などなど。
    もちろん1の概念や性質や観点は、どの数理論理フレームワークでも有効であり、それに基づいて個々の数理論理フレームワークも研究されるし、相互の特性の比較も為される。
  • 3. 具体的な問題解決のための数理論理
    これは例えばwumbus worldのエージェントを「論理」によって判断させる場合にあたる。

    • どの数理論理フレームワークを採用するかをきめる。
    • その数理論理フレームワークにおいて、環境や知識をどのように表現するかをきめる。
    • あとは数理論理フレームワークにて研究済みであるツールを用いて実行する。すなわちKBを構築し、推論し、行動し、あたらしい情報を知覚し、KBにそれを投入し、また推論し、と繰り返す。

    wumbus world以外の例としては、例えば、自然言語で考えられ構築されてきた数学の集合論の知識を一階述語論理という数理論理フレームワークを用いて表現し推論するというものがある。


この3つの階層に概念がわかれており、数理論理学で何かを語るときに、この階層を縦横無尽に行き来するということを理解していなかったから、今まで数理論理学がもやもやしていたのだ。

また「論理」という言葉の定義がかなり曖昧であり、文脈によって特定される機会がかなり多いこともその原因だったと思う。

「論理」が何を指しているかを理解するには、文脈がどうであるかを理解する必要があり、個別の文章の文脈を理解するには、数理論理学が概念や対象の階層構造を成していることを理解する必要があったということ。

これも大きな気づきだ。

2009年7月11日土曜日

【AIMAメモ】論理言語の意味論(Semantics)

意味論という言葉も厄介じゃないかなぁ。

まず、意味論として国語辞典、Semanticsとして英和辞書、英英辞書をみてももやもやしてわからない。これは例えば数学(Math)を国語辞典や英英辞典で見てもそれを理解できないのと同じことなのかな、と理解しておけばいいのだろうか。

でも、言葉としてのスケールが違うような?とも思う。

* この文のセマンティクスはどう決まっていますか?

というのが意味がありそうだと思えても、

* この文の数学はどう決まっていますか?

というのは無意味な質問に思える。数学と比してセマンティクスという言葉がスケールが小さいものにも適用できる言葉であるならば、辞書や辞典にもっと分かりやすい説明があってよいと思うのだが。。。

と考えていた。で、AIMAを読むとわかるのかわからないのか。


これが、わかるのだ。


x + y = 4 という文でAIMAは論理言語の意味論を説明している。それを私なりに咀嚼して書いてみよう。


  • まず、x + y = 4という文をみて我々はこの文を頭の中に入れることができる。ただしそれは+ x y 4 =であっても同じである。それらに比してx + y = 4というのは特別である。何故特別かというとそれはこの文に対する統語論を我々は学校で「算数」という名のもとに教えてもらっているからである。逆に言うと、+ x y 4 =は、「算数」という統語論では規則違反である。
  • 「算数」という統語論の中には、+ = 1 2 3 4などのconstantsとx yなどのvariablesが定義されており、文の構成素材として使用することができることも教えてもらっている。
  • xとyはvariablesなので、このx + y = 4という文に対してモデル(別名で可能世界)を考えることができる。例えば、「xが1、yが2であるようなモデル(世界)」「xが2、yが2であるようなモデル(世界)」などなど。これは「算数」ではconstansが無限にあることによって、モデルの数も無限になる。ここで大事なのは、ここでモデル云々の考え方は、「算数」の中で定義されているのではなく、論理言語一般の考え方ということだ。別の言葉でいうと、「算数」というものを論理言語の考え方で捉えて語っているのがこの文章であるということ。
  • さて、我々は x + y = 4という文において、「xが1、yが2であるモデル」ではこれが偽であり、「xが2、yが2であるモデル」ではこれが真であると言われると、それは合点がいくような気持になる。それはひとつの観点では、+ = 1 2 3 4などのconstansの意味を知っているからそれと照し合わせてそういう気持になるとも言えるが、そうすると意味って何よ?ということになってここが曖昧である。
  • そこを考えると我々がここで「意味」と認識しているものは、結局、
    x + y = 4 という文は、
    「xが1、yが1であるモデル」にて偽、
    「xが1、yが2であるモデル」にて偽、
    「xが1、yが3であるモデル」にて真、
    「xが2、yが1であるモデル」にて偽、
    「xが2、yが2であるモデル」にて真、
    ...
    ということ自体が展開された形での「意味」そのものではないか、ということになる。
  • すなわち、我々が「算数」という名称で教わったものは、「算数」としての文の書き方と、「算数」としてそれら文がどのようなモデルにて真偽値を取るかという対応であるということになる。この前者が「算数」の統語論(Syntax)であり、「後者」が意味論(Semantics)である。


スタートレックは異文化に対するイマジネーションに満ちているのでスタートレックのアナロジーを再度やってみよう。


  • Mr.スポック曰く、バルカン星では子供のころに「バルカニーナ」を教わる。
  • バルカニーナの統語論は、constansとして+ = 1 2 3 4であり、variablesとしてxとyがある。もちろん文の構造を決める他の文法規則もある。それら規則によると、x + y = 4は文とみなせるが、+ x y 4 = は違反であり文とみなせない。
  • バルカン星人は、 x + y = 4という文において、「xが2、yが2であるモデル」ではこれが偽であり、「xが1、yが1であるモデル」ではこれが真であると言われると、それは合点がいくような気持になる。それはひとつの観点では、+ = 1 2 3 4などのconstansの意味を知っているからそれと照し合わせてそういう気持になるとも言えるが、そうすると意味って何よ?ということになってここが曖昧である。
  • そこを考えるとバルカン星人がここで「意味」と認識しているものは、結局、
    x + y = 4 という文は、
    「xが1、yが1であるモデル」にて真、
    「xが1、yが2であるモデル」にて偽、
    「xが1、yが3であるモデル」にて偽、
    「xが2、yが1であるモデル」にて真、
    「xが2、yが2であるモデル」にて偽、
    ...
    ということ自体が展開された形での「意味」そのものではないか、ということになる。
  • すなわち、バルカン星人が「バルカニーナ」という名称で教わったものは、「バルカニーナ」としての文の書き方と、「バルカニーナ」としてそれら文がどのようなモデルにて真偽値を取るかという対応であるということになる。この前者が「バルカニーナ」の統語論(Syntax)であり、「後者」が意味論(Semantics)である。


これで明確になったと思うけど駄目おしを。

Dr.マッコイ:「x + y = 4」という暗号通信をクリンゴンの偵察挺が送信していたらしい。これはどういう意味だろう。

Mr.スポック:それは意味論により異なりますね。地球人はそれを算数の意味論に従っていると盲目的に解釈しがちですが、それは理性的ではありません。

Dr.マッコイ:「x + y = 4」に理性もへったくれもあるか!

Mr.スポック:感情的にならないでください。実際にバルカン星人にとっては、その文が適格である統語論でもっとも最初に習うのは「バルカニーナ」であり、「バルカニーナ」の意味論は地球人の「算数」の意味論とは違います。さらにバルカン星人の知識の中にある別の12の統語論においても「x + y = 4」を適格と見做すことができますがね。統語論と意味論をごちゃごちゃにして初等教育を行う地球人とは、バルカン星人は大きく異なるのです。バルカン星人は常に統語論と意味論を分けて学習します。

Dr.マッコイ:君だって地球人の血が半分流れてるじゃないか!



閑話休題。

x + y = 4 の意味論を算数とする

という表現がAIMAでもあるのですが、これはちょっとリスキーなんですね。私は今までこれがわからなかった。より混乱が少いのは、

x + y = 4 の意味論を、算数という名称で君や私が習った意味論にする。(統語論が算数と一致しているということは前提としている)

という表現である。

ああ、すっきりした。

【AIMAメモ】論理と物理

AIMAを読んでいて合点がいく部分が多いのは、物理との接続に言及しているところが大きいと思う。

たとえば、知識ベース(Knowledge Base,KB)のことを、物理的な構造にすぎないとズバリ言っている。ここでの物理的な構造は、電気的であったり有機化学的であったりするわけですが、この視座に立つとき、人間の知能というものと、計算機による知能(人工知能)というものを統一的に考えることができるようになる。これは気づき。

すなわち、(+ x 2)のようなものはこれが計算機のメモリ(電気的信号の状態)なのか、私の頭の中のこれを記憶している何らかの状態(電気的信号の状態 or 有機化学的な結合状態)なのか、いずれにしても物理的な状態を指している。

統語論(Syntax)が何かということも、それも物理的な構造としての文の形を規程するものとしている。

以下、以上の文脈にて。

KBは文の集まりである。文の統語論を命題論理としたとき、KB全体を単一の文(別の言い方をすると言明)とみなすことができる。これは、KBに含まれる文(論理)がS1,...,Snだったとすると、KB = S1^...^Sn (ここで^は連言)にすぎない、ということだ。言われてみれば当然なのだが、言われるとはっとする。

そしてそもそもこの単一の言明であるKBがそもそも現実世界において真であるかということをどうやって知るかということをグラウンディング(grounding)と言う。グラウンディングは哲学的論争になっているが、ひとつの立場は、センサという機器にて解釈する、ということだ。そもそも文の生成(すなわちKBの構築)にもセンサによる知覚が用いられる。そのことにより現実世界とKBはつながりをもちつづける。

実は、このような物理との接続がない状態で今まで人工知能の書籍を読んできたのですが(例えばPAIP)、どうも、どこがどういう観点で「知能」なのかということの座りがわるかった。例えば、macsymaが人の代わりに代数演算をするということも、確かに計算機という機械が人がやっていたことをやってくれるという観点では何かしらの人の知能的な側面を実現しているということでは人工知能だよねと自分を納得させていたのだが、腑に落ちないところもあった。

そういう意味では、このエントリは大きな気づき。

# センサと知るということになると量子論との接続はどうなのよ、と思ってしまうが、今は考えない。
# 日常的なオーダーの中での知覚と知能と行動については、まずはそのオーダーで良好な物理法則をベースに考えてもよいとは思う。
# それによって人間のKBも構築されてきたのだと思うから。

【AIMAメモ】論理のモデルと設計のモデル

これは、気づきではなくて、改めて確認したこと。

論理におけるモデルと設計におけるモデルとは随分違う。

文章にしてみて、より理解を堅牢にしてみたい。

まず、論理におけるモデルは、より具体的には、論理言語のモデルのことを指す。
次に、設計におけるモデルは、対象領域の記述のためのモデルのことを指す。

順番は逆になるが、それぞれさらに詳しくいうと。

対象領域の記述のためのモデルとは、例えばMVCにおけるモデルであり、それはドメインを分析した結果、そのドメインにおいてエクステントが比較的に長い概念や語彙のことである。

論理言語におけるモデルとは、今、ある論理言語にて書かれた文αがあるとして、そのαの真偽を考えるにあたって想像しうる(存在しうる)可能世界(possible world)のことである。

ということ。

ここでまず違うのが、

設計におけるモデルは現実に対する「何らかの抽象」と位置付けられているのに対して、
論理におけるモデルは論理文αに対する「何らかの(想像しうる)具象」と位置付けられている、

ということである。ただし、これら2つのモデルという言葉の用法がunification可能かどうか考えてみると、これはできそうだ。

設計におけるモデルというのは抽象ではあるが、それはいろいろ考えうる抽象のうちの一つであり、その中から設計の選択として実装に使用するモデルを選択しているということである。これって可能世界としてありうるものの一つという感覚と似てなくもない。

こう書いてみると、抽象と具象というのはN:Mな関係であることに気づいた。ある抽象を決めれば、それを満たす具象がいろいろあると考えられる(具象群)。OOにおけるクラスとオブジェクトの関係。具象群からある抽象をつくるとは、その具象群の抽象の形というのはいろいろありえるわけで(抽象群)、その中から選択をする行為とも考えられる。まあ、実際に設計をするということは、この双方をいったりきたりして、フィードバックをかけてチェックしつつうまい抽象化というのを探索している行為と考えられるのですが。


ちなみにSPINなどのModel checkerのモデルとは、論理の方のモデルのことですね。

【AIMAメモ】論理(logic)の誤解

誤解していた。これは大きな気づきだ。

論理(logic)というのを、日常の「あの人、論理的だよねー」とかそういう言い回しが三段論法的な話し方を指したりすることに引っ張られて、何か手法であったり知識を使うために運用するものだと今まで暗黙に思っていた。違うのだ。論理は知識の表現そのものなのだ。それを運用するのは推論規則なのだ。

Mr.スポック的にいうと、

知識 <-(論理的思考法)- Mr.スポック

なんだけど、これでは計算機科学的には間違っていて、

知識(論理による表現) <-(推論規則)- アプリケーション(探索実装)

なのだ。だから、

logic <- control

によって計算機から具体的な結果が得られ、これが

Algorithm = logic + control.

そしてこのlogicの部分が宣言的プログラミング、
このcontrolの部分が手続き的プログラミング。

2009年7月10日金曜日

【AIMAメモ】知識工学とDSL

そうか、知識工学って今でいうDSLとかなりクロスオーバーしているものなんだ!

DSL : システム分析 -> ドメイン分析 -> ドメインモデル -> 手続き/永続化実装 -> 基本的なデータの投入 -> DSLとして利用
知識工学 : システム分析 -> ドメイン分析 -> 語彙と知識表現の決定 -> 知識を表現 -> 推論エンジンを介して利用

前半戦に類似がある。

【AIMAメモ】ブログエントリの考え方

さて、途中から読んでみると、頭から読むのとやり方が違うのがすぐにわかった。ゲリラ的というかなんというか。のっけから自分なりの理解を組み立てるしかないので、読み方も縦横無尽になる。わかっているところから切り崩していく感じ。これはこれでおもしろい。もしかしたら、この方がよい読書方法なのかもしれないなぁ。でも著者と膝を突き合わせる感じでじっくり最初から読んでいくのが好きなんだけどね。

さて、そんなこんなで、今回のAIMAアタックにおいては、気づきがあったところなどを散発的にメモとしてエントリに上げようと思う。なので小さなエントリがちょこちょこ出ると思う。

AIMAをかじる

せっかく得たPrologの理解(イロハのイだが)もたぶんすぐに消えてしまう。今はまだ、日々ごりごりプログラムを書く状態じゃないから。

そうするとこれが消えないうちに、PrologとFOLとLispとをもうすこし繋いでおきたい。どうしたもんかなぁ、FOLを数理論理学の本できっちりやるのは、それはそれで時間がかかるしなぁ、と思案してたんだけど、これAIMA(Artificial Inteligence a Modern Approach)をやればいいじゃん!ということに気付いた。AIMAにはFOLについて簡潔にまとめた部分があるのです。PAIPやってて、Prologやったところだから、Norvigつながりもあって結構よい組み合わせではないか。

AIMAのFOLは8章と9章なんで、頭から読んでいるとPrologを忘れちゃう。そこで、思い切って7章からやろうと思う。7章から論理エージェントが初まる。

本を途中から読むということに慣れていないので、うまくいかないかもしれない。うまくいくかもしれない。チャレンジしてみよう。

こつこつ。

2009年7月9日木曜日

Allegro Prolog

以前はまったくわからんかったが、今はわかる!!

Allegro Prolog

LispとPrologとを多少連携して使えるみたい。

PAIPやりながらAllegro Prologもいじってみることにする。これは楽しみ。


CL-USER(2): (require :prolog)
; Fast loading /opt/acl81.64/code/prolog.002
;;; Installing prolog patch, version 2.
T
CL-USER(3): (use-package :prolog)
T
CL-USER(4): (?- (append ?x ?y (1 2 3)))
?X = ()
?Y = (1 2 3)
?X = (1)
?Y = (2 3)
?X = (1 2)
?Y = (3)
?X = (1 2 3)
?Y = ()
No.
CL-USER(5): (<-- (likes Kim Robin))
LIKES
CL-USER(6): (<- (likes Sandy Lee))
LIKES
CL-USER(7): (<- (likes Sandy Kim))
LIKES
CL-USER(8): (<- (likes Robin cats))
LIKES
CL-USER(9): (?- (likes Sandy ?x))
?X = LEE
?X = KIM
No.
CL-USER(10):

12 Working With Files


* 12 Working With Files
** 1 Splitting Programs over Files
- consult
- [FileName]. (at top-level)
- 実体はconsultという述語らしい。
- ファイルの中で使うときは頭に:-をつけるようだ。
- ensure_loaded
- ensure_loaded([FileName]).は、読み込み済みで無
変更なものは再読み込みしないようだ。
- module
- そのファイルをmoduleにする。
- :- module(ModuleName,
List_of_Predicates_to_be_Exported).
- use_module
- moduleを使う。
- :- use_module(ModuleName).
- importする述語の指定(制限)もできる。
- :- use_module(ModuleName,
List_of_Predicates_to_be_imported).
- library
- 処理系にてライブラリとして定義されているもの
を指定する。use_moduleとあわせて使う。
- 例:
:- use_module(library(lists)).

** 2 Writing to Files
- streamがある。使い方はこんな感じ。

open('hoge.txt',wrie,Stream),
write(Stream,'This is hoge.',nl(Stream),
close(Stream).

** 3 Reading from Files
- read/2
- streamからPrologのtermsを読み込む。
- streamが読むものがないとエラーになる。
- at_end_of_stream/1
- streamの終端の検知。
- get_code/2
- streamからcharacterをひとつ読む。

** 4 Exercise
- Exercise 12.1.

main :-
open('hogwarts.houses',write,Stream),
tab(Stream,10),write(Stream,'glyffindor'),nl(Stream),
tab(Stream,3),write(Stream,'hufflepuff'),tab(Stream,4),write(Stream,'ravenclaw'),nl(Stream),
tab(Stream,10),write(Stream,'slytherin'),nl(Stream),
close(Stream).

- Exercise 12.2.

:- dynamic word/2.

main :-
open('swipl-man.txt',read,S),
doWords(S),
close(S).

readWord(InStream,W) :-
get_code(InStream,Char),
checkCharAndReadRest(Char,Chars,InStream),
atom_codes(W,Chars).

checkCharAndReadRest(10,[],_) :- !.
checkCharAndReadRest(32,[],_) :- !.
checkCharAndReadRest(-1,[],_) :- !.
checkCharAndReadRest(end_of_file,[],_) :- !.
checkCharAndReadRest(Char,[Char|Chars],InStream) :-
get_code(InStream,NextChar),
checkCharAndReadRest(NextChar,Chars,InStream).

doWords(InStream) :-
\+ at_end_of_stream(InStream),
readWord(InStream,W),
writeWord(W),
doWords(InStream).

writeWord(Word) :-
Word \== '', memoize(Word).
writeWord('').

memoize(W) :-
word(W,N),M is N+1,asserta(word(W,M)),retract(word(W,N)),!.
memoize(W) :- asserta(word(W,1)).

** 5 Practical Session
- 今まで作ってきたものをモジュール化して統合。
- モジュール名と、ファイル名の拡張子より前は、同
じでないといけないみたい。
- Step 2までにしておき、後は入出力の練習なので、
割愛する。


読了!!!!
頭がくたくただ!

【LPN】10 Cuts and Negation [落葉拾い]

いずれも寝た後なら簡単だった。疲れたときにも頑張ることは、意味がないのかなぁ。

- Exercise 10.4.

うーん。むずかしい。cutは宣言的かつ手続き的なの
で、慣れれば強力かもしれないが、慣れないと中途
半端で考えにくい。特にunificationがどう効いてく
るかが問題になると、自分で束縛管理した方が楽じゃ
んと思えてしまう。

ここは後日、再チャレンジ。

一晩寝たら5分でできた。。。

directTrain(saarbruecken,dudweiler).
directTrain(dudweiler,saarbruecken).
directTrain(forbach,saarbruecken).
directTrain(saarbruecken,forbach).
directTrain(freyming,forbach).
directTrain(forbach,freyming).
directTrain(stAvold,freyming).
directTrain(freyming,stAvold).
directTrain(fahlquemont,stAvold).
directTrain(stAvold,fahlquemont).
directTrain(metz,fahlquemont).
directTrain(fahlquemont,metz).
directTrain(nancy,metz).
directTrain(metz,nancy).


route(From,To,Route) :- rt(From,To,[To],Route).
rt(From,From,A,A) :- !.
rt(From,To,A,Route) :-
directTrain(From,To),
rt(From,From,[From|A],Route).
rt(From,To,A,Route) :-
directTrain(ViaSt,To),
rt(From,ViaSt,[ViaSt|A],Route).


** 5 Practical Session
- 1.

\+ version.

nu(A,B) :- \+ A = B.

\+ cut-free version

nu(A,B) :-
A = B, fail;
A \= B.

cut-fail combination version

nu(A,B) :- A = B, !, fail.
nu(_,_).

- 2.

頭がまわらないので、これも後日。

これも一晩寝たら30分くらいでできた。

unifiableUni(Term1,Term2) :-
atomic(Term1),atomic(Term2),
Term1 = Term2.
unifiableUni(Term1,Term2) :-
var(Term1);
var(Term2).
unifiableUni(Term1,Term2) :-
complexterm(Term1),
complexterm(Term2),
Term1 =.. [F1|Args1],
Term2 =.. [F2|Args2],
F1 = F2,
unifiableLists(Args1,Args2).
unifiableLists([],[]).
unifiableLists([H1|T1],[H2|T2]) :-
unifiableUni(H1,H2),
unifiableLists(T1,T2).

unifiableAcc([],Term,A,A).
unifiableAcc([H|T],Term,A,R) :-
unifiableUni(H,Term),
unifiableAcc(T,Term,[H|A],R),!;
unifiableAcc(T,Term,A,R).

unifiable(List1,Term,List2) :-
unifiableAcc(List1,Term,[],List2).


こつこつ。

【LPN】11 Database Manipulation and Collecting Solutions


* 11 Database Manipulation and Collecting Solutions
** 1 Database Manipulation
- assert/1。む、swi-prologはちょっと変なことを言う。

?- listing.
true.

?- assert(happy(mia)).
true.

?- listing.

:- dynamic happy/1.

happy(mia).
true.

?-

- ファイルから読み込んだものはstatic predicates、
REPL?で定義したものはdynamic predicates。
- retract : 撤回する
- swi-prologではretractの対象がDBに複数あるとき、
バックトラック的な操作で全て消せる。

?- retract(happy(vincent)).
true ;
true.

?- listing.

:- dynamic happy/1.

happy(butch).

:- dynamic naive/1.

naive(A) :-
happy(A).
true.

?-

- assertはmemoisaitonに使える。
- database manipulationの迂闊な利用はnightmareだか
ら注意して。

** 2 Collecting Solutions
- findall/3はちょっとmap的。
- bagof/3、便利。
- setof/3、便利。

** 3 Exercise
- Exercise 11.1.
- 第一段階

q(foo,blug).
q(a,b).
q(1,2).

- 第二段階

q(foo,blug).
q(a,b).
p(X) :- h(X).

- 第三段階

p(X) :- h(X).

- Exercise 11.2.
- findall(X,q(blob,X),List).
List = [blug,blag,blig].
- findall(X,q(X,blug),List).
List = [blob,dang].
- findall(X,q(X,Y),List).
List = [blob,blob,blob,,blaf,dang,dang,flab].
- bagof(X,q(X,Y),List).
Y = blug,
List = [blob,dang].
Y = blag,
List = [blob,blaf].
Y = blig,
List = [blob].
Y = dong,
List = [dang].
Y = blob,
List = [flab].
- setof(X,Y^q(X,Y),List).
List = [blaf,blob,dang,flab].

- Exercise 11.3.
- まずこう書いた。
sigma(0,0).
sigma(N,S) :-
M is N - 1, M >= 0,
T is S - N, T >= 0,
sigma(M,T),!,
asserta((:- sigma(N,S))).

- これはpredicateとしては使えるが、構築には使え
ない。

?- sigma(5,15).
true.

?- sigma(10,X).
ERROR: is/2: Arguments are not sufficiently instantiated
^ Exception: (9) _L143 is _G174-10 ?

- traceで調べる。

?- trace.
Unknown message: query(yes)
[trace] ?- sigma(2,X).
Call: (7) sigma(2, _G303) ?
^ Call: (8) _L180 is 2-1 ?
^ Exit: (8) 1 is 2-1 ?
^ Call: (8) 1>=0 ?
^ Exit: (8) 1>=0 ?
^ Call: (8) _L181 is _G303-2 ?
ERROR: is/2: Arguments are not sufficiently instantiated
^ Exception: (8) _L181 is _G303-2 ?
Exception: (7) sigma(2, _G303) ?
?-

- なるほど。Unificationのinstantiationがいまい
ちつかめていないのだな。accumulatorを使おう。

sigma(N,S) :- sigmaAcc(N,0,S),!,asserta((sigma(N,S))).
sigmaAcc(0,A,A) :- !.
sigmaAcc(N,A,S) :-
M is N - 1,
NewA is A + N,
sigmaAcc(M,NewA,S).

assertaが

ERROR: asserta/1: No permission to modify static_procedure `sigma/2'

を吐く。これはまた別の問題なので割愛する。

** 4 Practical Session
- 1.

subset([],_).
subset([H|T],[H|ST]) :-
subset(T,ST).
subset([H|T],[SH|[H|ST]]) :-
subset(T,[SH|ST]).

backtrackで出力する集合に重複があるけどそれは勘
弁。

- 2.

powerset(L,P) :-
findall(X,subset(X,L),P).

先の重複の問題があるので、同じ集合だけど並びが
違うものも含んでしまっている。

?- powerset([a,b,c],P).
P = [[], [a], [a, b], [a, b, c], [a, c], [a, c, b], [b], [b|...], [...|...]|...].

これらの手落ちは後日時間があったらやろう。


よろよろ。

2009年7月8日水曜日

【LPN】10 Cuts and Negation


* 10 Cuts and Negation
** 1 The Cut
- ! : predicate called cut.
- cutは常に成功する。副作用する。副作用が大事。
- fat-freeじゃなくてcut-free。
- commit A to do,doing : Aに...することを義務づけ
る。
- cutを踏んだ時点で2つのことが義務となる。1つめは、
現在のproof searchにおいて、そのclauseのみを探
索の対象とすること(他のclauseは除外するというこ
と)。次に、cutを踏む前にunify済みの変数について
は、これ以降unificationは実施しないこと。
** 2 Using Cut
- green cuts : cutsを入れても入れなくてもプログラ
ムの意味(入出力の対応)に変化はないもの。green
cutsに意味があるのは、効率があがるときである。
- red cuts : cutsの有り無しでプログラムの意味が変
わるcuts。
- red cutsがある、ということはそのプログラムがあ
まり宣言的ではない証左。なるほど。
** 3 Negation as Failure
- fail/0 : バックトラックを強制する述語。
- cut-fail combination : failによるバックトラック
を抑制するイディオム。このイディオムがくると、
そこでproof search自体がfailする(バックトラック
しない)。
- この章に入って、Prologの手続き的側面がどんどん
導入されていく。。
- negation : Monadic Boolean operations whose
result have the Boolean value opposite to that
of the operand.
- cut-failじゃなくてnegation as failureを使うほう
が安全。

neg(Goal) :- Goal,!,fail.
neg(Goal).

- \+ : built-in negation as failure predicate.

- cutsとnegation as failureの使い方についての完全
なルールは存在しないケースバイケースの判断が必
要。

- まあ、プログラミングは、科学であるのと同じくら
い芸術(技芸)でもあるので、自身が選択した言語と
問題領域について理解を常に深めなければならない。
だから面白いんだよ、プログラミングは。など。
** 4 Exercises
- Exercise 10.1.
p(X).
X = 1.
X = 2.

p(X),p(Y).
X = 1, Y = 1.
X = 1, Y = 2.

これ、間違えた。正解は、


?- p(X),p(Y).
X = 1,
Y = 1 ;
X = 1,
Y = 2 ;
X = 2,
Y = 1 ;
X = 2,
Y = 2.

?-

ということ。p(Y)でのcutはp(X)の探索には影響を及
ぼさないことに注意。

p(X),!,p(Y).
X = 1, Y = 1.
X = 1, Y = 2.

- Exercise 10.2.

class(Number,positive) :- Number > 0.
class(0,zero).
class(Number,negative) :- Number < 0.

これは数字のクラスに関する述語。正か負かゼロか
でクラス分けしている。

green cutsによる効率化。

class(Number,positive) :- Number > 0,!.
class(0,zero) :- !.
class(Number,negative) :- Number < 0.

- Exercise 10.3.

まず、cut-free。

split([],[],[]).
split([LH|LT],[LH|PT],N) :-
LH >= 0, split(LT,PT,N).
split([LH|LT],P,[LH|NT]) :-
LH < 0, split(LT,P,NT).

続いてgreen cuts。

split([],[],[]) :- !.
split([LH|LT],[LH|PT],N) :-
LH >= 0, !, split(LT,PT,N).
split([LH|LT],P,[LH|NT]) :-
LH < 0, !, split(LT,P,NT).

- Exercise 10.4.

うーん。むずかしい。cutは宣言的かつ手続き的なの
で、慣れれば強力かもしれないが、慣れないと中途
半端で考えにくい。特にunificationがどう効いてく
るかが問題になると、自分で束縛管理した方が楽じゃ
んと思えてしまう。

ここは後日、再チャレンジ。



** 5 Practical Session
- 1.

\+ version.

nu(A,B) :- \+ A = B.

\+ cut-free version

nu(A,B) :-
A = B, fail;
A \= B.

cut-fail combination version

nu(A,B) :- A = B, !, fail.
nu(_,_).

- 2.

頭がまわらないので、これも後日。


よろよろ。

【LPN】9 A Closer Look at Terms


* 9 A Closer Look at Terms
** 1 Comparing Terms
- ==/2はCommon Lispのeqみたいなニュアンスかな。

?- a == a.
true.

?- a == b.
fail.

?- a == 'a'.
true.

?- X == Y.
fail.

?- X=Y.
X = Y.

?- a = X, a == X.
X = a.

?-

- ふむ、eval、、、ではなくunifyされたobjectsを
eq、、、じゃなく==は等価性チェックする。
- ただ、==はtrue/failだけでなく、unifyされている
ときは、unification(binding)を返しているな。な
んか気になる。
- \==/2の導入。

** 2 Terms with a Special Notation
- Arithmetic terms

?- (2 =:= 3) == =:=(2,3).
true.

?- 2 =:= 3 == =:=(2,3).
ERROR: Syntax error: Operator priority clash
ERROR: 2 =:=
ERROR: ** here **
ERROR: 3 == =:=(2,3) .
?-

- なるほど。

- List as terms

?- .(a,[]) == [a].
true.

?- .(a,.(b,[])) == [a,b].
true.

?-
- おお、consだ!会いたかったよ、cons。こんなに小
さくなっちゃって。。。

** 3 Examining Terms
- Types of Terms
- termsの型を調べる述語たち。

- The structure of Terms

?- functor(f(a,b),F,A).
F = f,
A = 2.

?-
- おお、functorとarityも取れるのね。

?- functor(T,hoge,1).
T = hoge(_G240).

- 構成もしてくれる、と。

- complex termに対する型判定述語は自分で作る。

complexterm(X) :-
nonvar(X),
functor(X,_,A),
A > 0.

- arg : 引数に対するアクセス。
- =.. : complex termsのfunctorとargsをリストで返
す。univと呼ばれる。
- atom_codes/2にてatomとstringの相互変換ができる。

** 4 Operators
- ?-というのはprefix operatorだったのか。
- precedenceが大きいものが主たる(:外側の)functor
になる。+と*でいうと+の方が優先度が大きいので

2 + 3 * 4.

は、

+(2,*(3,4)).

になる。優先度が高い = 結合度が低い、かな。

- operatorsとpredicatesが同義語なのかそうでないの
かがわからない。先々わかるかな。
- precedenceが同じoperatorsが存在する場合どうなる
か。それはoperatorsのassociativityという概念/機
構によって振る舞いがきまる。
- 例えば、+は左結合性をもっている(left
associative)。
- 左結合性をは何か?
- まずexpressionsのprecedenceの概念がある。それは
そのexpressionの主functorのprecedenceである。さ
て、左結合性とは、infix operatorsなのでそもそも
引数は左右の2つなのだが、左にいれるexpressionは
自身と同じprecedenceでもよいが、右にいれる
expressionは自身より低くないといけない。これに
よって、

2 + 3 + 4.

は、

+(+(2,3),4).

というように曖昧さなく解釈される。ためす。

?- 2 + 3 + 4 = +(+(2,3),4).
true.

?- 2 + 3 + 4 = +(2,+(3,4)).
fail.

なお、これは内側のoperatorが+でなくても(同じで
なくても)適用される。

- ==, =:= は同じprecedenceを持ち、かつ
non-associtiveである。すなわち、左右引数双方と
も自身よりもprecedenceが低い必要がある。そのた
め、

2 =:= 3 == =:=(2,3).

が、

==((2 =:= 3),=:=(2,3)).

なのか、

=:=(2,==(3,=:=(2,3))).

なのかをPrologは自動判定できない。

- Defining operators
- operatorsというのは、operatorとして構文定義され
たpredicatesのことのようだな。逆に言うと、op
operatorが定義するのは構文だけで、それの意味と
いうかその演算の結果がどうなるかは通常のqueryと
同じであるということ。

?- assert(kill(marcellus,zed)).
true.

?- kill(X,zed).
X = marcellus.

?- assert((is_dead(X) :- kill(_,X))).
true.

?- is_dead(zed).
true.

?- op(500,xf,is_dead).
true.

?- zed is_dead.
true.

?- is_dead zed.
ERROR: Syntax error: Operator expected
ERROR: is_dead
ERROR: ** here **
ERROR: zed .

?-

** 5 Exercise
- Exercise 9.1.
- 12 is 2*6.
true.
- 14 =\= 2*6.
true.
- 14 = 2*7.
true. /* 正しくはfail。unifyは計算しない。term
の種類が違う。*/
- 14 == 2*7.
fail.
- 14 \== 2*7.
true.
- 14 =:= 2*7.
true.
- [1,2,3|[d,e]] == [1,2,3,d,e].
true.
- 2+3 == 3+2.
fail.
- 2+3 =:= 3+2.
true.
- 7-2 =\= 9-2.
true.
- p == 'p'.
true.
- p =\= 'p'.
fail. /* 正しくはERROR.数字じゃないので計算で
きない */
- vicent == VAR.
fail
- vincent=VAR,VAR==vincent.
true.

- Exercise 9.2.
- .(a,.(b,.(c,[]))) = [a,b,c].
true.
- .(a,.(b,.(c,[]))) = [a,b|c].
fail
- .(.(a,[]),.(b,[]),.(.(c,[]),[])) = X.
ERROR. /* 最外の.の引数が3つ。*/
お、ERRORにならない。そうか'.'/3が定義されるの
か!
- .(a,.(b,.(.(c,[]),[]))) = [a,b|[c]].
fail. /* [a,b,[c]] */
- Exercise 9.3.

complexterm(X) :-
nonvar(X),
functor(X,_,A),
A > 0.

termtype(Term,atom) :-
atom(Term).
termtype(Term,number) :-
number(Term).
termtype(Term,constant) :-
atomic(Term).
termtype(Term,variable) :-
var(Term).
termtype(Term,simple_term) :-
atomic(Term);
var(Term).
termtype(Term,comprex_term) :-
complexterm(Term).
termtype(_,term).

- Exercise 9.4.

groundterm(X) :-
atomic(X), nonvar(X).
groundterm(X) :-
nonvar(X),
X = [H|T],
groundterm(H),
groundterm(T).
groundterm(X) :-
complexterm(X),
'=..'(X,[functor|Args]),
groundterm(Args).

- Exercise 9.5.

- うー。operatorの結合めんどくさい。S式でいいじゃん。

X is_a witch
is_a(X,witch).

harry and ron and hermione are friends
are(and(harry,and(ron,haermione)),friends)

harry is_a wizard and likes quidditch
illegal.

dubledore is_a famous wizard
is_a(dubledore,famous(wizard)).

** 6 Practical Session
- pretty printer

pptree(T) :- ppt(T,0).
ppt(T,I) :-
atomic(T),tab(I),write(T).
ppt(T,I) :-
complexterm(T),
'=..'(T,[Functor,Single]),
tab(I),write(Functor),write('('),write(Single),write(')').
ppt(T,I) :-
complexterm(T),
'=..'(T,[Functor,Left,Right]),
tab(I),write(Functor),write('('),nl,
NewI is I + 2,
ppt(Left,NewI),nl,
ppt(Right,NewI),write(')').

- propositional logic formulas

:- op(200,fx,not).
:- op(300,xfy,implies).


さすがに体調が悪くなってきた。
仕事との両立が難しいのか、体が弱いのか。

こつこつ。