Wiki
Clone wikiCafeOBJ / OSEK / contents / ceiling
半順序集合の極
任意の半順序集合を(S,R)とする. Sの要素xが,任意のSの要素yに対して y R x とならないとき, x をRに関するSの極と呼ぶことにする. このとき,次の定理が成り立つ.
定理:Sが空でなければ,SにはRに関する極が存在する.
これを論理式で表現すると,S ≠ {} ⇒ ∃x∈S・(∀y∈S・¬(y R x))となる. これを証明しよう.
CafeOBJによる定理の表現
上の定理をCafeOBJで証明するためには,定理そのものをCafeOBJで表現する必要がある.
まず,関係Rを次のように集合上に拡張する.
#!python module EXTEND ( X :: TRIV, C :: SET(X), R :: RELATION(X) ) { signature { op ___ : Set Relation Set -> Prop } axioms { vars X Y : Elt vars C D S : Set vars R : Relation eq X R nil = true . eq nil R C = false . eq X R (C,Y) = (X R C) and (X R Y) . eq (S,X) R C = (S R C) or (X R C) . } }
2つの集合SとTに対して,Tの全ての要素yに対して x R y が真となる要素xがSに存在するとき, S R T は真となる.
次に,2項関係の反転を次のように宣言する.
#!python module REVERSE ( X :: TRIV, R :: RELATION(X) ) { signature { op ~ : Relation -> Relation } axioms { vars X Y : Elt vars R : Relation eq X ~(R) Y = Y R X . } }
モジュールREVERSEでは,関係を反転させる演算~を宣言している. 任意の項xおよびyに対し,x ~(R) y が真になるのは y R x が真になるときである.
#!python module NEGATE ( X :: TRIV, R :: RELATION(X) ) { signature { op ! : Relation -> Relation } axioms { vars X Y : Elt vars R : Relation eq X !(R) Y = (not X R Y) . } }
モジュールNAGATEで宣言されている演算!は,いわば関係の否定を表す. 任意の項xとyに対し,x R y が偽となるとき,x !(R) y は真となる.
任意の集合CとC上の関係Rに対して, Cに関係Rに関する極が存在することはC !(~(R)) C で表現できる. 任意のCの要素yに対して,x !(~(R)) y が真となる要素xが存在することは C !(~(R)) C は真となることと等価であり, x !(~(R)) y が真であることは,not(x ~(R) y) が真,すなわち, not(y R x) が真であることと等価である.
補題
さて,上に挙げた性質を証明する前に,補題を1つ証明しておこう. CをソートSの項を要素とする任意の集合,RをS上の推移的関係,xとyをSの任意の項とし, x !(~R)) C が成り立つとする. このとき,y R x であれば,y !(~(R)) C が成り立つ. この補題は,次のモジュールで宣言される演算inheritを用いて表されるシーケント inherit(x,y,C,R)で表現される.
#!python module INHERIT ( X :: TRIV, C :: SET(X), R :: RELATION(X), T :: TRANSITIVE(X,R), N :: NEGATE(X,R), V :: REVERSE(X,R), E :: EXTEND(X,C,R) ) { imports { pr(SEQUENT) } signature { op inherit : Elt Elt Set Transitive -> Sequent } axioms { vars X Y : Elt vars C : Set vars R : Transitive eq inherit(X,Y,C,R) = (Y R X), (X !(~(R)) C) |- (Y !(~(R)) C) . } }
補題の証明
任意の集合c,推移的関係r,並びにcの要素x,yに対して, シーケントinherit(x,y,c,r)が真となることをcに関する構造帰納法を用いて示そう.
まず,cが空である場合にinherit(x,y,c,r)が真になることを示す.
#!python open INHERIT . ops x y : -> Elt . ops c : -> Set . ops r : -> Transitive . eq c = nil . red hold(inherit(x,y,c,r)) = true . close
これを実行すると次のようになる.
#!python CafeOBJ> open INHERIT . opening module INHERIT(X, C, R, T, N, V, E).. done. %INHERIT(X, C, R, T, N, V, E)> ops x y : -> Elt . %INHERIT(X, C, R, T, N, V, E)> ops c : -> Set . %INHERIT(X, C, R, T, N, V, E)> ops r : -> Transitive . %INHERIT(X, C, R, T, N, V, E)> eq c = nil . _ %INHERIT(X, C, R, T, N, V, E)> red hold(inherit(x,y,c,r)) = true . * reduce in %INHERIT(X, C, R, T, N, V, E) : (hold(inherit(x,y,c,r)) = true):Bool (true):Bool (0.000 sec for parse, 7 rewrites(0.000 sec), 28 matches) %INHERIT(X, C, R, T, N, V, E)> close CafeOBJ>
次に,inherit(x,y,c,r)が真であると仮定しよう. このとき,cに新たに要素zを追加してできる集合nに対しても, inherit(x,y,n,r)が真になることを示す.
#!python open INHERIT + LK . ops x y z : -> Elt . ops r : -> Transitive . ops c n : -> Set . eq n = (c,z) .
帰納法の仮定「inherit(x,y,n,r)が真」であることは次のように宣言される. 最初に,見やすさのため(x !(~(r)) c)と(y !(~(r)) c)を各々pxとpyに略記しておく.
#!python ops px py : -> Prop . eq (x !(~(r)) c) = px . eq (y !(~(r)) c) = py .
演算holdには評価戦略を陽に与えていないため, 項hold(inherit(x,y,c,r))の簡約は引数inherit(x,y,c,r)の簡約から始まる. その場合,inherit(x,y,c,r) が真であることを直接等式
#!python eq hold(inherit(x,y,c,r)) = true .
で宣言しても,この等式は簡約に適用されない. ここでは,inherit(x,y,c,r)を簡約した項((y r x), px |- py)が真であることを等式で宣言し, inherit(x,y,c,r)が真と評価されるようにしている.
#!python eq hold((y r x), px |- py) = true .
実際にこれで帰納法の仮定が成り立つことは次の簡約で確かめられる.
#!python red hold(inherit(x,y,c,r)) .
以下に示す簡約結果にあるように,帰納法の仮定は成り立っている.
#!python -- reduce in %RULE + INHERIT + INFERENCE(X.INHERIT, C.INHERIT, R.INHERIT, T.INHERIT, N.INHERIT, V.INHERIT, E.INHERIT) : (hold(inherit(x,y,c,r))):Bool (true):Bool (0.000 sec for parse, 4 rewrites(0.000 sec), 21 matches) %RULE + INHERIT + INFERENCE(X.INHERIT, C.INHERIT, R.INHERIT, T.INHERIT, N.INHERIT, V.INHERIT, E.INHERIT)>
それでは,集合cに要素zを加えた集合nに対しても,inherit(x,y,n,r)が真となることを示そう. 次の推論iとjを考えCafeOBJで次のように記述する.
推論iは,次のように記述できる
#!python ops i j : -> Inference . eq antecedent(i) = ((y r x), (z r y), px |- (z r x)) . trans ((y r x), (not z r x), px |- (not z r y)) => consequent(i) . trans consequent(i) => ((y r x), (not z r x), px |- (not z r y)) .
推論iの前提((y r x), (z r y), px├ (z r x))は関係rの推移律より正しい. 推論iの結論は,このシーケントから命題(z r y)と(z r x)を入れ替えて得られる. 因みに,結論の表現方法は,両方向の書換規則により表現される. これは,モジュールINFERENCEで表される推論を積み重ねる場合, 先の推論の結論を後の推論の前提として扱えるようにするためである. 一般に,書換論理では,両方向の書換規則は等式と等価になるので, この2つの書換規則で,書換の両辺は等しいことが表される.
推論jは次のように記述される.
#!python op j : -> Inference . eq antecedent(j) = (consequent(i), ((y r x), (not z r x), px |- py)) . eq ((y r x), ((not z r x) and px) |- ((not z r y) and py)) = consequent(j) .
推論jの前提は,推論iの結論にシーケント((y r x), (not z r x), px |- py))を加えたものである. シーケントの左辺への∧導入規則により,この2つのシーケントから ((y r x), ((not z r x) and px) |- ((not z r y) and py))という, inherit(x,y,n,r)と等価なシーケントが導かれる. なお,ここでは,推論jの結論consequent(j)を等式で定めている. これは,jの結論を他の推論の前提として扱う必要がないからである.
ここで,シーケントinherit(x,y,n,r)が真になることを確かめよう.
#!python red hold(inherit(x,y,n,r)) .
項hold(inherit(x,y,n,r))はtrueに書換えられる.
#!python %LK + INHERIT(X.INHERIT, C.INHERIT, R.INHERIT, T.INHERIT, N.INHERIT, V.INHERIT, E.INHERIT)> red hold(inherit(x,y,n,r)) . -- reduce in %LK + INHERIT(X.INHERIT, C.INHERIT, R.INHERIT, T.INHERIT, N.INHERIT, V.INHERIT, E.INHERIT) : (hold(inherit(x,y,n,r))):Bool ** Found [state 265] (consequent(j)):Sequents {} -- found required number of solutions 1. ** Found [state 95] (consequent(i)):Sequents {} -- found required number of solutions 1. (true):Bool (0.000 sec for parse, 3477 rewrites(1.180 sec), 292338 matches, 1570 memo hits)
以上より,xとyをソートSの任意の項,CをソートSの項を要素に持つ任意の集合,RをS上の推移的関係とすると, シーケント (y R x), (x !(~(R)) C)├ (y !(~(R)) C)が真となることが証明されたので, モジュールINHERITを次のように書き換えよう.
#!python module INHERIT ( X :: TRIV, C :: SET(X), R :: RELATION(X), T :: TRANSITIVE(X,R), N :: NEGATE(X,R), V :: REVERSE(X,R), E :: EXTEND(X,C,R) ) { imports { pr(JUDGEMENT) } axioms { vars X Y : Elt vars C : Set vars R : Transitive eq hold((Y R X), (X !(~(R)) C) |- (Y !(~(R)) C)) = true . } }
定理の証明
それでは,この補題を用いて冒頭に紹介した定理を証明しよう. 定理の主張を宣言するモジュールBOUNDEDを宣言する.
#!python module BOUNDED ( X :: TRIV, C :: SET(X), R :: RELATION(X), I :: IRREFLEXIVE(X,R), A :: ASYMMETRIC(X,R), T :: TRANSITIVE(X,R), P :: PARTIAL-ORDER(X,R,I,A,T), N :: NEGATE(X,R), V :: REVERSE(X,R), E :: EXTEND(X,C,R), L :: INHERIT(X,C,R,T,N,V,E) ) { imports { pr(SEQUENT) } signature { op bounded : Set PartialOrder -> Sequent } axioms { vars C : Set vars R : PartialOrder eq bounded(C,R) = (not C = nil) |- (C !(~(R)) C) . } }
定理の主張は, 「(C,R)を任意の半集合とすると,Cが空でなければCはRに関する極を持つ」ことであった, これは,上のモジュールで宣言した演算を用いれば,bounded(C,R)と書ける. この主張が真であることを,Cに関する構造帰納法で示そう.
まず,Cが空集合の場合に主張が真であることを示す.
#!python -- [base case] c = nil open BOUNDED . op c : -> Set . op r : -> PartialOrder . eq c = nil . red hold(bounded(c,r)) . close
この証明譜を実行すると,主張bounded(c,r)は真であることがわかる.
#!python CafeOBJ> -- opening module BOUNDED(X, C, R, I, A, T, P, N, V, E, L).. done. %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> _ %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> * -- reduce in %BOUNDED(X, C, R, I, A, T, P, N, V, E, L) : (hold(bounded(c,r))):Bool (true):Bool (0.000 sec for parse, 8 rewrites(0.000 sec), 29 matches)
次に,cに対して主張が真であることを仮定して, cに要素xを付け加えた集合nでも主張が真になることを示す.
ここで,cが空である場合と空でない場合に場合分けを行う.
【場合1】cが空である場合
この場合,証明譜は次のように書ける.
#!python -- [induction step] -- [case division] -- [case1] c = nil open BOUNDED . ops c n : -> Set . ops x : -> Elt . ops r : -> PartialOrder . eq n = (c,x) . eq c = nil . red hold(bounded(n,r)) . close
この証明譜を実行すると,確かに主張は真になることがわかる.
#!python -- opening module BOUNDED(X, C, R, I, A, T, P, N, V, E, L).. done. %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> _ %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> * -- reduce in %BOUNDED(X, C, R, I, A, T, P, N, V, E, L) : (hold(bounded(n,r))):Bool (true):Bool (0.000 sec for parse, 12 rewrites(0.000 sec), 38 matches)
【場合2】cが空でない場合
帰納法の仮定より,cにはrに関する極yが存在する. cからyを取り除いた集合をsと置き,cをsとyの和で表現しよう.
#!python -- [case2] not c = nil open BOUNDED . ops x y : -> Elt . ops r : -> PartialOrder . ops s c n : -> Set . eq c = (s,y) . eq n = (c,x) .
(y !(~(r)) c) は (y !(~(r)) s) に簡約されるので, yがrに関するcの極であることを次のように宣言する.
#!python eq (y !(~(r)) s) = true .
そして,xとyに関して,次の2つの場合を考える.
【場合2a】(x r y)が真でない
【場合2b】(x r y)が真である
(x r y)が真でない場合は,次の証明譜により主張が成り立つことが容易に示せる.
#!python -- [case division] -- [case2a] (not x r y) = true eq (not x r y) = true . red hold(bounded(n,r)) . close
この証明譜の実行結果は次のようになる.
#!python %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> %BOUNDED(X, C, R, I, A, T, P, N, V, E, L)> * -- reduce in %BOUNDED(X, C, R, I, A, T, P, N, V, E, L) : (hold(bounded(n,r))):Bool (true):Bool (0.000 sec for parse, 30 rewrites(0.000 sec), 444 matches)
(x r y)が真である場合は,LKに基く推論を用いて次のように証明される. (x r y)が真でない場合と同様に,要素x,y,半順序r,集合s,c,nを各々次のように宣言する.
#!python -- [case2b] (x r y) = true open BOUNDED + LK . ops x y : -> Elt . ops r : -> PartialOrder . ops s c n : -> Set . eq c = (s,y) . eq n = (c,x) .
ここで,yがrに関するcの極であることや(x r y)が真であることをシーケントを用いて次のように表す.
#!python eq hold(nil |- (y !(~(r)) s)) = true . eq hold(nil |- x r y) = true .
そして,証明に不要な項を纏めてpと略記することにする.
#!python ops p : -> Prop . eq ((s !(~(r)) (s , (y , x))) or ((y !(~(r)) s) and (not (x r y)))) = p .
このとき,主張が真であることは下の推論で示せる.
各推論i,j,kをCafeOBJで証明譜として記述すると以下のようになる.
#!python ops s1 s2 s3 s4 : -> Sequent . eq s1 = ((x r y),(y !(~(r)) s) |- ((x !(~(r)) s), p)) . eq s2 = (nil |- x r y) . eq s3 = (nil |- (y !(~(r)) s)) . eq s4 = (((x r y), (y r x)) |- nil) . ops i j k : -> Inference . eq antecedent(i) = (s1,s2,s3) . trans (nil |- ((x !(~(r)) s), p)) => consequent(i) . trans consequent(i) => (nil |- ((x !(~(r)) s), p)) . eq antecedent(j) = (s2,s4) . trans (nil |- (not y r x)) => consequent(j) . trans consequent(j) => (nil |- (not y r x)) . eq antecedent(k) = (consequent(i),consequent(j)) . eq (nil |- (((x !(~(r)) s) and (not y r x)) or p)) = consequent(k) .
ここで,consequent(k)はbounded(n,r)と等しい
#!python red bounded(n,r) == consequent(k) . %LK + BOUNDED(X.BOUNDED, C.BOUNDED, R.BOUNDED, I.BOUNDED, A.BOUNDED, T.BOUNDED, P.BOUNDED, N.BOUNDED, V.BOUNDED, E.BOUNDED, L.BOUNDED)> red bounded(n,r) == consequent(k) . -- reduce in %LK + BOUNDED(X.BOUNDED, C.BOUNDED, R.BOUNDED, I.BOUNDED, A.BOUNDED, T.BOUNDED, P.BOUNDED, N.BOUNDED, V.BOUNDED, E.BOUNDED, L.BOUNDED) : (bounded(n,r) == consequent(k)):Bool (true):Bool (0.000 sec for parse, 28 rewrites(0.000 sec), 819 matches)
主張が正しいことを示すには,次の簡約を実行すればよい.
#!python red hold(bounded(n,r)) . close %LK + BOUNDED(X.BOUNDED, C.BOUNDED, R.BOUNDED, I.BOUNDED, A.BOUNDED, T.BOUNDED, P.BOUNDED, N.BOUNDED, V.BOUNDED, E.BOUNDED, L.BOUNDED)> red hold(bounded(n,r)) . -- reduce in %LK + BOUNDED(X.BOUNDED, C.BOUNDED, R.BOUNDED, I.BOUNDED, A.BOUNDED, T.BOUNDED, P.BOUNDED, N.BOUNDED, V.BOUNDED, E.BOUNDED, L.BOUNDED) : (hold(bounded(n,r))):Bool ** Found [state 35] (consequent(k)):Sequents {} -- found required number of solutions 1. ** Found [state 27] (consequent(j)):Sequents {} -- found required number of solutions 1. ** Found [state 1925] (consequent(i)):Sequents {} -- found required number of solutions 1. (true):Bool (0.000 sec for parse, 6639 rewrites(7.130 sec), 1040611 matches, 3944 memo hits)
この定理に基き,任意の半順序集合を(C,R)とすると, CからRに関する極を1つ取り出す演算を定義しても構わないことが保証される.
#!python module CEILING ( X :: TRIV, C :: SET(X), R :: RELATION(X), I :: IRREFLEXIVE(X,R), A :: ASYMMETRIC(X,R), T :: TRANSITIVE(X,R), P :: PARTIAL-ORDER(X,R,I,A,T) ) { signature { op ceiling : Set PartialOrder -> Elt } axioms { vars X : Elt vars C : Set vars R : PartialOrder cq ceiling(C,R) @ C = true if not(C = nil) . cq not(X R ceiling(C,R)) = true if not(C = nil) and X @ C . } }
Updated