2002-08-28
λ. DRb vs Gtk::Plug & Gtk::Socket
なかださんが「面白そう」と言ってくれたので、試しに簡単なものを作ってみる。細かなエラー処理などは省略。
# drbembed.rb
require 'drb'
require 'gtk2'
module DRbEmbed
class Socket < Gtk::Socket
def initialize
super()
@drbobj = nil
end
def add(arg)
@drbobj = arg
add_id(@drbobj.__drb_embed_plug_id__)
end
end
end
module Gtk
class Widget
def __drb_embed_plug_id__
if parent
unless parent.is_a? Gtk::Plug
raise TypeError.new("parent isn't Gtk::Plug")
end
else
Gtk::Plug.new.show.add(self)
end
parent.id
end
end
end
次に埋め込まれるWidgetの例。DRbを普通に使ってるだけ。
require 'drbembed'
server = DRb::DRbServer.new(nil, Gtk::Button.new('This is remote widget'))
puts server.uri
Gtk.main
で、このWidgetをリモートから使ってみる。コンテナとしてDRbEmbed::Socketを使う事以外、ほとんど何も気にしなくて良いはず。
require 'drbembed'
there = ARGV.shift || raise("usage: #{$0} <server_uri>")
DRb.start_service(nil, nil)
remote_widget = DRb::DRbObject.new(nil, there)
win = Gtk::Window.new
socket = DRbEmbed::Socket.new
win.add(socket)
win.show_all
socket.add(remote_widget)
remote_widget.show
remote_widget.signal_connect('clicked'){
puts 'Hello DRb!'
}
Gtk.main
う〜ん。もう少し改良の余地があるかな。
2005-08-28
λ. クロージャ
もちろん、Haskellでも出来ますよ。
ioCounter :: IO (IO Integer)
ioCounter =
do ref <- newIORef 0
return $ do modifyIORef ref (1+)
readIORef ref
test =
do c <- ioCounter
c >>= print -- => 1
c >>= print -- => 2
【2006-03-28 追記】 鷲見さんの sumim’s smalltalking-tos の 「Perl6 あなどれじ。クロージャ記述の短さ対決!」というエントリのコメントで、このコードを元に増分を毎回指定できるようにしたバージョンが紹介されていた。面白い。
2006-08-28
λ. 人狼SNSに参加
stinさんに招待していただいたので、参加。 stinさん、ありがとうございました。
<URL:http://wolfsbane.jp/?m=pc&a=page_f_home&target_c_member_id=474>
2007-08-28
λ. ビジネス実務マナー技能検定試験2級
合格していた。
λ. Paradoxes of classical predicate calculus
The Coq Proof Assistant - A Tutorial の「Paradoxes of classical predicate calculus」のところが面白い。古典一階述語論理だと Smullyan's drinkers' paradox 「In any non-empty bar, there is a person such that if she drinks, then everyone drinks」が証明できてしまうそうだ。 へぇ。
例によってagdaで示してみる。
drinker (!D::Set) (!d::D)
(!EM::(X::Set) -> Either X (Not X))
(!P::D->Set)
:: Exist (\(x::D)-> P x -> (y::D) -> P y)
drinker =
case EM (Exist (\(x::D) -> Not (P x))) of
(Left e )->
struct
fst :: D
fst = e.fst
snd :: P fst -> (y::D) -> P y
snd = \(px::P fst) -> case e.snd px of { }
(Right ne)->
let f (!x::D) :: P x
f = case EM (P x) of
(Left px )-> px
(Right npx)->
let e :: Exist (\(x::D) -> Not (P x))
e = struct
fst :: D
fst = x
snd :: Not (P fst)
snd = npx
in case ne e of { }
in struct
fst :: D
fst = d
snd :: P fst -> (y::D) -> P y
snd = \(z::P d) -> f
ところで、zyxwvさんが謎と思っているのはどの部分なんだろう? 一階述語論理の推論規則の話だろうか?
一階述語論理の推論規則には 「∀x.P[x] から P[t] を導く規則」や「P[t] から ∃x.P[x] を導く規則」が含まれている(ヒルベルト流でも自然演繹でもシーケント計算でも)。 ここでビミョーなのが一階述語論理では勝手に自由変数を置いて使える点。 そのため、一階述語論理では勝手に置いた自由変数tについて (∀x.P[x]) → P[t] が証明出来る。同様に P[t] → (∃x.P[x]) も証明できるため、それらから (∀x.P[x]) → (∃x.P[x]) も証明出来る。 しかし、論理式の意味を考えると、∀x.P[x] は領域が空なら真である一方で、∃x.P[x] は領域が空なら偽だし、さらに P[t] は領域が空なら解釈不能になってしまう。 これらの矛盾を避けるため、一階述語論理のモデル論では領域Dは空集合でないこと前提とされている。
一方、Coq等の基づいている型理論では自由変数を勝手に置いたり出来無いため、これらを一階述語論理の場合と同様に証明する証明することは出来ないし、またDが空集合である場合も許される。 そのため、ここでは一階述語論理を模すため、Dの要素dの存在を明示的に仮定している。
(追記: 「定数記号」と書いていた部分を「自由変数」に変更した)
![[カタツムリ]](./images/s20080828_0.jpg)
