2015年6月21日日曜日

SBCL での defclass slot の :type オプションの挙動


defclass の slot には、:type オプションを指定することができる。

期待としては、:type オプションを指定した場合、指定した型を満たさない値を代入しようとすると、エラーとなって欲しい。ところが、SBCL ではそのようにならない。

(defclass foo ()
  ((x :accessor foo-x
      :initarg :x
      :type integer)))

(let ((x (make-instance 'foo :x 1)))
  (setf (foo-x x) :foo)
  (foo-x x))                           ; => :foo

defclass と slot へのアクセスを optimize safety で評価すると、期待する挙動となる。

(locally (declare (optimize safety))
  (defclass foo ()
    ((x :accessor foo-x
        :initarg :x
        :type integer)))

  (let ((x (make-instance 'foo :x 1)))
    (setf (foo-x x) :foo)              ; error
    (foo-x x)))

CLHSには、以下のようにあるものの、

The consequences of attempting to store in a slot a value that does not satisfy the type of the slot are undefined.

その前の部分には以下のようにある。

The :type slot option specifies that the contents of the slot will always be of the specified data type.

SBCL User Manualには以下のようにあり、その理由は示されていない。悲しい。

Types declared using the :type slot option in defclass are asserted if and only if the class was defined in safe code and the slot access location is in safe code as well.


2015年4月28日火曜日

2015年3月4日水曜日

A list of Physics-Based Animations

Here shows a list of physics-based animations I computed and rendered, including fluid, rigid body and their coupling simulation. Movies are to be added.


Falling Rigid Bunnies
I simulated a lot of falling Stanford bunnies and rendered the result.

watch movie


Bunny-shaped fluid simulation
I simulated bunny-shaped fluid body and rendered the result.

watch movie



Rigid-fluid coupling for SPH
I simulated rigid-fluid coupling for SPH and rendered the result.

watch movie



Rigid-fluid coupling for SPH
I simulated rigid-fluid coupling for SPH and rendered the result.

watch movie



Rigid body simulation on a slope
I simulated a rigid body falling on a slope with a particle-based method.

watch movie



Falling rigid bodies
I simulated falling rigid bodies and rendered the result.

watch movie



Particle-based rigid body simulation
I simulated many colliding rigid bodies and rendered the result.

match movie



Braking wave simulation with SPH
I simulated a breaking wave with SPH and rendered the result.

watch movie


Particle-based fluid simulation in x2 scale
I computed the following fluid simualtion in x2 scale, then rendered the result.

watch movie


Particle-based fluid simulation in 3D
I computed particle-based fluid simulation in 3D and rendered the result.

watch movie



Particle-based fluid simulation
I computed particle-based fluid simulation in 2D and rendered the result.

watch movie



2015年3月1日日曜日

PIC - PIC Is a Compiler for 8-bit PIC micro controllers


PIC is a native compiler for 8-bit PIC micro controllers written in Common Lisp. The host language is a pretty small subset of ML-like language and the target language is 8-bit PIC micro controller assembly. Common Lisp is the compiler language.

Usage
Following is an example of LED blinking with PIC12F683 micro controller. init function is one of the compiler's special functions, where the micro controller's SFR(Special Function Registers) are initialized. Following main function is also the compiler's special function and program's main routine is executed here.

mdelay1 function and mdelay macro are for delaying. Note that since 8-bit PIC handles only 8-bit unsigned integers, nested loops are needed for delaying more than 255 msec (950 msec here). progn and loop are predefined macros for the compiler.
(defpic init ()
  (progn
    (setreg :gpio #x0)                  ; clera GP0-5
    (setreg :cmcon0 #x07)               ; disable comparator
    (setbank1)                          ; switch to bank 1
    (setreg :trisio #x08)               ; only GP3 is outputinputmode
    (setreg :ansel #x00)                ; disable analog IO
    (setreg :ioc #x00)                  ; disable interruption
    (setbank0)                          ; switch to bank 0
    (setreg :intcon #x00)))             ; disable interruption

(defpic main ()
  (progn
    (setreg :gpio #x20)                 ; set GP5 to high
    (mdelay 50)                         ; delay for 50 msec
    (setreg :gpio #x00)                 ; set GP5 to low
    (mdelay 950)                        ; delay for 950 msec
    (main)))                            ; repeat

(defpic mdelay1 ()
  (loop 90                              ; 90 is a magic number to delay
    0))                                 ;  for 1 msec

(defpicmacro mdelay (n)
  (unless (<= 0 n 65535)
    (error "The value ~S is invalid." n))
  (multiple-value-bind (q r) (truncate n 256)
    (if (= q 0)
        `(loop ,r (mdelay1))
        `(loop ,q (loop ,r (mdelay1))))))
Then pic-compile function compiles and outputs the complete assembly for the PIC functions to standard output. The output assembly is expected to be assembled with Microchip's MPASM assembler.
PIC> (pic-compile)
    INCLUDE"p12f683.inc"
    list p=12f683

    __CONFIG _CP_OFF & _CPD_OFF & _WDT_OFF & _BOD_ON & _IESO_OFF& _PWRTE_ON & _INTOSCIO & _MCLRE_OFF

    CBLOCK  020h
    L0,L1,L2,L3,L4,L5,L6,L7 ; local registers
    I0,I1,I2,I3,I4,I5,I6,I7 ; input registers
    SP,STMP,STK             ; stack registers
    ENDC

    ORG 0
    GOTO    MAIN
    ...
    END
; No value
For detail, please see its repository.


2014年12月1日月曜日

Swank RPC プロトコル


Swank RPC プロトコルは、SLIME と Swank との間で用いられる、テキストベースの非同期通信プロトコルです。

SLIME は、Common Lisp でアプリケーションを開発するための Emacs モードで、IDE(統合開発環境)と呼べるほど強力な機能を備えています。

SLIME には、Swank と呼ばれるバックエンドがあります。Swank は、Common Lisp プロセスにロードされ、ソケットを経由して SLIME と通信します。このとき使用されるのが、Swank RPC プロトコルです。

Swank RPC プロトコルの概観


Swank RPC プロトコルは、6文字の16進数文字列とそれに続くS式、終端の改行文字で構成されます。

000016(:return (:ok nil) 1)\n

先頭の16進数文字列は、続くS式の長さ(最後の改行文字を含む)を表します。S式は、SLIME や Swank によって読み込まれます。S式の最初の要素はメッセージの種類を表すキーワードで、残りの要素がその引数です。

メッセージには、以下のような種類があります。

  • :emacs-rex
  • :return
  • :indentation-update
  • :new-features

Swank RPC プロトコルによるS式の評価


たとえば、(+ 3 4)というS式を Swank で評価するには、以下のメッセージを送信します。

00002c(:emacs-rex (+ 3 4) "COMMON-LISP-USER" t 1)\n

最初の6文字は続くS式の長さで、改行文字を含め44文字のため、16進数で2cとなります。

メッセージの種類は :emacs-rex (Remote EXecute SEXP)で、第一引数が評価するS式、第二引数がそのときのカレントパッケージです。第三引数はS式の評価を行う Swank 側のスレッドを表し、第四引数は戻り値を受け取る継続を意味します。

S式が評価されると、Swank からは以下のようなメッセージが返信されます。

000013(:return (:ok 7) 1)

最初の6文字は、送信されたメッセージと同様にS式の長さを表し、19文字のため、16進数で13となります。

戻り値を表すメッセージは、:return です。評価に成功した場合、第一引数の最初の要素が :ok となり、二番目の要素に評価した結果の値が入ります。ここではその値は7です。第二引数は、送信されたメッセージの第四引数に含まれていた継続がそのまま返されます。

まとめ


このように、Swank RPC プロトコルでは、S式で表現されたテキストベースのメッセージが相互にやりとりされます。SLIME と Swank のやり取りの様子は、Emacs の *slime-events* バッファでみることができます。


2014年5月30日金曜日

cl-coroutine: a coroutine library for Common Lisp


CL-COROUTINE is a coroutine library for Common Lisp. It uses CL-CONT continuations library in its implementation.


https://github.com/takagi/cl-coroutine

;; define a coroutine using DEFCOROUTINE macro 
(defcoroutine example (whom) 
  (format t "First greeting to: ~A~%" whom) 
  (yield 1) 
  (format t "Second greeting to: ~A~%" whom) 
  (yield 2) 
  (format t "Third greeting to: ~A~%" whom) 
  (coexit 3) 
  (format t "No greeting to: ~A~%" whom) 
  (yield 4)) 
=> EXAMPLE 

;; make a coroutine object 
(setf coroutine (make-coroutine 'example)) 
=> a coroutine object 

;; funcall it 
(funcall coroutine "Smith") 
>> First greeting to: Smith 
=> 1 

I want your feedback. Thanks.

 

SBCL (Steel Bank Common Lisp) のビルドプロセス

SBCL のビルドプロセスの外観


Common Lisp の実装の1つである SBCL (Steel Bank Common Lisp) のビルドプロセスは、Allegro Common Lisp や LispWorks といった、イメージベースでそれ自身の上でのみビルド可能な Common Lisp 実装とは異なり、SBCL 以外の Common Lisp 実装の上でもビルドできます。それを実現するために、SBCL のビルドプロセスでは、様々なテクニックが使われています。

このエントリでは、SBCL のビルドプロセスを順を追って説明します。

host-1 ビルドステージ


まず、ホスト上にクロスコンパイラを読み込みます。SBCL のソースコードをホストコンパイラでコンパイルしロードすることで、ホスト上にクロスコンパイラを展開します。

続いて、後のステージのための前処理として、sb!fasl:genesis の読み込みと、C ヘッダファイルの出力を行います。sb!fasl:genesis は、genesis-2 ビルドステージで、'cold core' を生成するために使われます。C ヘッダファイルは、続く target-1 ビルドステージで、SBCL の実行形式を構築するのに使われます。

target-1 ビルドステージ


target-1 ビルドステージでは、大きく2つの処理が行われます。1つは、SBCL 実行形式の構築です。host-1 ビルドステージで生成された C ヘッダファイルと、その他の C ソースファイルおよびアセンブリファイルから、SBCL の実行形式を構築します。ただし、この実行形式は、この時点ではまだ動作しません。OS サービスへのインターフェイスやガベージコレクタを提供するものの、次ステージ以降で生成されるターゲットメモリイメージを含まないためです。

もう1つの処理は、ターゲットの一部として使用される Lisp ソースコードの生成です。この Lisp ソースコードは、小さな C プログラムをコンパイルおよび実行することで生成され、システム依存の定数と型に関する情報を提供します。

host-2 ビルドステージ


このステージでは、SBCL 用のオブジェクトファイル (FASL ファイル) が生成されます。オブジェクトファイルは、クロスコンパイラ版の compile-file を用いて、SBCL ソースコードを再度コンパイルすることで得られます。このとき、SBCL ソースコードの他に、host-1 ビルドステージで生成した Lisp ソースコードを併せて用いることで、クロスコンパイラ上の定数定義を、システム環境に応じたものに更新します。

genesis-2 ビルドステージ


続いて、genesis-2 ビルドステージに入ります。ここでは、host-1 で読み込んだ sb!vm:genesis を用いて、FASL ファイルのロードとメモリイメージの保存をシミュレートします。sb!vm:genesis が必要となる理由は、ホストコンパイラの load 関数では、SBCL の FASL 形式をロードできず、また、SBCL のターゲットイメージがまだ存在しないことからその load 関数を使うこともできないためです。

ここで行う処理は、次のように進みます。まず、特定の順序で擬似的に FASL ファイルをロードし、メモリイメージを展開します。次に、ターゲットのメモリ領域をバイト配列とみなし、FASL ファイルをロードしたときに起こるであろう処理をシミュレートします。この方法で実行できない処理は、ターゲットイメージの初期化関数が実行されるまで遅延されます。すべての FASL ファイルがこの方法で処理された後、メモリ領域を SBCL 実行形式が期待する形式でファイルに保存します。これで 'cold core' が生成されました。

最後に、'cold core' をメモリイメージとして、SBCL 実行形式を起動します ('cold init')。遅延されていたトップレベル・フォームの処理などは、このタイミングで実行されます。'cold init'は、助けになる Lisp デバッガが存在しないことから最もデバッグしづらいため、現在の SBCL のビルドプロセスにおいて、もっとも脆弱な箇所といえます。

target-2 ビルドステージ


SBCL のビルドプロセスの最終ステージが、target-2 ビルドステージです。まず、パッケージを最終的な名前に変更し、sb! プレフィックスを、sb- プレフィックスとします。次に、SBCL に特殊化されたバージョンの Portable Common Loops (PCL) をコンパイルし、ロードします。最後に、そうしてできた新しいメモリイメージを、output/sbcl.core として保存します。

これで、ビルドプロセスが完了しました。

まとめ


このエントリでは、SBCL のビルドプロセスを順を追って説明しました。SBCL のアプローチにもメリット・デメリットはありますが、このような仕組みでセルフ・ブートストラッピングを実現しているというのは、興味深いところです。

参考


SBCL - a Sanely-Bootstrappable Common Lisp
http://www.doc.gold.ac.uk/~mas01cr/papers/s32008/sbcl.pdf
 

2014年5月20日火曜日

Cl-reexport: symbol reexporting library for common lisp


Cl-reexport is a library to reexport symbols which are external symbols in other packages. It is valuable when virtually construct package hierarchy on Common Lisp standard's flat package system. 

https://github.com/takagi/cl-reexport 

ASDF 3 has similar one-package-per-file facility. The structural difference between them is: 


* Virtual hierarchy packages in this context have one system definition and several packages constituting a hierarchical structure. 

* ASDF 3's one-package-per-file style has hierarchical system definitions and hierarchical packages, which are corresponding each other. 

Since ASDF 3's one-package-per-file style has not been de facto standard yet, there may be some cases where cl-reexport is useful. 

Currently requesting to Quicklisp to register. 

I want your feedback.