　　　　　　　　　　　　　　　　ＥｕｓＬｉｓｐ
　　　　　　　　　　　オブジェクト指向に基づくLispの実現と
　　　　　　　　　　　　　　　幾何モデラへの応用


　　　　　　　　　　　松井俊浩　　　    　　　　　稲葉雅幸
　　　　　　　　　電子技術総合研究所　　    　　東京大学工学部
　　　　　　　　　matsui@etl.junet　　　　　inaba@mech.t.u-tokyo.junet

　　　　　　　　　1.　Lisp・オブジェクト指向とロボット・幾何モデル
　　　　　　　　　2.　EusLisp のオブジェクト指向
　　　　　　　　　3.　EusLisp の内部構造
　　　　　　　　　4.　幾何モデリング機能
　　　　　　　　　5.　他言語インタフェースとウィンドウシステム



ロボット、CAD などのための幾何モデラの実現を主たる目的として、単一継承型のオブジ
ェクト指向に基づくCommonLispのサブセット、EusLisp を開発した。EusLisp では、コン
スやシンボルなどの基本データ型もオブジェクトとして定義している。これらのデータ型
にサブクラスを加えることで、システムの拡張が容易に行なえる。拡張されたデータ型に
対しても効率よく基本関数を適用するための高速型判別法や、擬似的な多重継承を実現す
るためのメッセージフォワーディングの機能を実装している。幾何演算プリミティブを関
数として用意し、幾何モデルの要素をオブジェクトとして定義することで、拡張性の高い
ソリッドモデラを簡潔に記述することができる。また、関数とシンボルの拡張で実現され
た他言語インタフェースを用いてライブラリをリンクすることにより、Lisp上のウィンド
ウシステムが容易に構築できる。

SIGSYM-50-2

"EusLisp: An Object-Based Implementation of Lisp and Its Application to
 Geometric Modeling"

by Toshihiro MATSUI (Autonomous Systems Section, Electrotechnical Laboratory,
Tsukuba-city, Ibaraki, 305, JAPAN; E-mail matsui%etl.jp@relay.cs.net) and
Masayuki INABA (Department of Mechanical-Engineering, University of Tokyo,
Tokyo, 113, JAPAN).


Aiming at the realization of a geometric modeler in Lisp for Robotics and CAD,
an object-based subset of CommonLisp, EusLisp has been developed.
Since EusLisp defines all the data types except numbers in terms of objects,
all the system facilities are highly extensible through the class inheritance.
Based on EusLisp's object-orientation, a solid modeler which has capabilities
for composing objects by set-operations and displaying hidden-line eliminated
images in several window environments, has been built. The greatest advantage
over the traditional modelers is the extensibility to the higher level appli-
cations in robotics field.


matsui@etl.junet   matsui%etl.jp@relay.cs.net
inaba@mech.t.u-tokyo.junet
１．Euslisp の目的と特徴
　高性能ワークステーション上のCommonLisp[1] によっ
て、Lispの実用的応用分野が広がりつつある。ロボット
の研究もそのような応用分野の１つである。
　ロボットの研究では、作業・動作のプラニング、経路
の探索、ワールドモデルの管理、環境の認識、マンマシ
ン・インタフェースなど種々の要素技術とそれらを統合
するシステム化技術が重要になる。これらの問題に共通
的に必要な機能は、３次元物体の形状と振る舞いを記述
するための幾何モデラである。幾何モデラには、頂点、
稜線、面などの間の位相関係を記述する能力と、浮動小
数演算を含む幾何的計算を効率よく処理する能力が要求
される。さらに、幾何モデルを認識や作業計画に応用す
るには、幾何モデルは拡張を加え易くなけらばならず、
多くのプログラムの統合を図る機能が必要になる。
　これらの要求に応えるために、オブジェクト指向をベ
ースにしたCommonLispのサブセット†、Euslisp を開発
した。Euslisp は、①オブジェクト指向による高い拡張
性[8] 、②幾何演算機能と幾何モデリング[9] 、③他言
語インタフェースによる外部プログラムの統合とウィン
ドウ環境の実現[10]、などを特徴とする。特に、システ
ムの基本部分をオブジェクトによって構成しているので
、それらのサブクラスを定義する形で豊富な機能を統合
することに成功している。また型の判別法を工夫するこ
とで、オブジェクト指向を導入することによる効率の劣
化も最小限に抑えている。
　本論文では、Euslisp のオブジェクト指向、メモリ管
理を含む内部構造、幾何モデリング機能、他言語インタ
フェースを用いたウィンドウシステムについて述べる。

２．Euslisp のオブジェクト指向
2.1 オブジェクト指向とLispの型拡張
　Lispは、古典的な記号・リスト処理言語から、豊富な
デ−タ型を扱う言語に発展して来ており、今後も型追加
の要求は続くものと思われる。システムの基本データ型
に対してクラスの継承によるサブタイプ化が可能であれ
ば、システムのインプリメントとアプリケーション開発
の両方が容易になる[2] 。このような型拡張を、組み込
み型とユーザ定義型の間でトランスペアレントに行なう
ために、Euslisp では数値以外のデータをすべてオブジ
ェクトとして表現している。defstruct,CLOS[3] などと
異なるのは、コンス、シンボル、文字列などのLispの組
み込みデータ型もオブジェクトであり、ユーザが定義す
るオブジェクトと本質的に同一の構造を持つ点である。
一方、数をオブジェクトとしなかったのは、数値演算の
効率を重視したためである。
　組み込み型の追加によってシステムの機能が拡張され
る例をいくつか上げよう（図１参照）。多バイト文字列
は単純文字列の、ウィンドウはストリ−ムの副型として
定義できる。ストリ−ムに対しては、ファイルと文字列
を別クラスとし、さらにIPC 用にパイプ、ソケット、メ
ッセ−ジキュ−等をストリ−ムに加えることができる。
シンボルは属性付きオブジェクトのサブクラスとなって
いる。これによって、属性リストの管理がシンボルから
分離され、シンボル以外のオブジェクトも属性リストを
利用できるようになる。コンスは、使用目的に応じて、
alist,set,stack 等を派生させることができる。alist
やset に対しては、assoc,member関数の:test 引数に応
じたクラスを作成できる。これは、ハッシュ表がtest関
数をmake-hash-table の時点で指定していることを考え
れば何ら不自然ではない。クロージャはコンパイルドコ
ードにレキシカルな環境の情報を加えたオブジェクトと
して定義される。この他に４章、５章で述べるように、
幾何モデル要素の階層化や他言語インタフェースのため
の拡張にもクラスの継承は有効に機能している。
　defstruct によるユーザデ−タ型定義と異なり、Lisp
の組み込みデ−タ型を拡張できれば、Lispシステムの資
産をフル活用でき、システム自体の拡張性が高まる。さ
らに、Lispの組み込み型が外部にオ−プンになっている
ため、Lispのインプリメントが容易になる。つまり、組
み込み型を増やすにつれ、要素にアクセスする関数を多
数用意しなければならなくなるが（symbol-value,symbo
l-function,symbol-package などと、それらのsetfマク
ロ）Euslisp のアプロ−チではこれらはすべてEuslisp
自身で記述可能である。
　クラスの定義はdefclassマクロで、メソッド定義はde
fmethod 特殊形式で行なう。メタクラスやクラスメソッ
ドを定義することも可能である。インスタンスの作成は
instantiate 関数で、メッセージの送信はsendとsend-s
uper関数で行なう。

2.2 クラスの階層に則った型判別法
　継承による型の拡張を許す場合、基本型に対して定義
された関数は、副型に対しても適用できるべきである。
たとえば、ストリ−ムのサブクラスであるsocket-strea
m に対してもread,print等の関数はそのまま適用可能で
なければならない。そのために、すべての関数をメッセ
−ジ送信に置き換えたり、CommonLispのようにdeftype
によって任意の型のコンビネ−ションを図る方法は柔軟
性に富むが、実行に探索を伴い、インライン展開が困難
になるので効率上得策とは言えない。これに対し、型の
階層を単一継承に限れば、次のような効率的な型判別が
可能である。
　オブジェクトには、元になったクラスを示す指標とし
てcid(class-id; 0..65535) を記録しておく。また、ク
ラスには、自分のcid と共に自分のサブクラスのcid の
うちで最大のもの（maxsubcid)をも記録しておく。オブ
ジェクトｘが、クラスＣまたはＣのサブクラスから生成
されたことを検査するためには、ｘのcid がＣのcid と
maxsubcid の間にあるかどうかを調べればよい。すなわ
ち、C.cid ≦x.cid ≦C.maxsubcid 。
　このような検査法を可能にするために、クラスＣの順
序付けられた直接のサブクラスＣ1 ..Ｃn のcid,maxsub
cid を以下のように定める（図２参照）。
　サブクラスなし　Ｃ.maxsubcid =  Ｃ.cid
  サブクラスあり　Ｃ1.cid=Ｃ.cid＋１
　　　　　　　　　Ｃi+1.cid=Ｃi.cid ＋１
　　　　　　　　　Ｃ.maxsubcid= Ｃn.maxsubcid ＋１
　この関係を保つため、継承木の下端以外に新しいクラ
スが登録されるときはcid の再割り付けが必要になる。
この処理には全オブジェクトのcid の書き換えが含まれ
るので、オブジェクトの総量に比例した時間を要する。
しかし、クラス定義は頻繁に起こるものではないので大
きな問題とはならない。定義時にこのような手間をかけ
ておけば、実行時には簡単なレンジチェック命令だけで
型判別が可能となる。実際、クラスＡがクラスＢのサブ
クラスであるかどうかを調べるsubclassp,オブジェクト
ｘがクラスＡまたはそのサブクラスから導出されたかど
うかを調べるderivedp関数はコンスタントタイムで実行
される。

2.3 メッセージ・フォワーディング
　Euslisp では、システムの根底にオブジェクト指向を
据えている。オブジェクト指向と高い効率を発揮するLi
sp処理系を共存させるためには、前節で述べたような型
の判別法が重要であるが、本手法を多重継承に拡張する
のは困難であり、単一継承を採用せざるを得ない。Eusl
isp の前身となった、多重継承型オブジェクト指向プロ
グラミング機能LEO [7] での経験では、①多重継承では
スーパクラスのどのメソッドが実行されるかを常に意識
せねばならず、スーパクラスの組み合わせ方が難しい、
②is-aの関係でなく、part-of の関係の方が柔軟な構成
を取れる、などが明らかになっていた。このように、必
ずしも多重継承がよいと言い切れるものではないが、と
きに多重継承によれば簡潔に記述できる問題があるのも
事実である。また、単一継承だけでは、vectorが seque
nce とarray の両方のサブタイプであるという構造を表
せない。
　Euslisp では、単一継承の簡潔性と高い効率を保ちつ
つ多重継承の機能を取り入れるため、メッセージフォワ
ーディングの機能を実現している。これは、あるオブジ
ェクトにメッセージが送られ、それがそのクラスで処理
できないことがわかると、:forward指定されたスロット
にメッセージを送り直す機能である。これは、サブクラ
ス、スーパクラスの間で変数を共有しないような多重継
承と等価な機能を提供する。図３の例ではpresident に
送られた:telephone,:mailメッセージはsecretary に、
:go-homeメッセージはchauffeur に自動再送信される。
　メソッド探索には、プロセスにグローバルな512 エン
トリのメソッドキャッシュを用いており、幾何モデラの
アプリケーションでは、９９％以上のヒット率を得てい
る。フォワードされたメッセージに対してもキャッシュ
を適用することで、高い効率を維持することが可能と思
われる。
３．ポインタ、オブジェクトの構造と記憶管理
3.1 ポインタの構造
　ポインタは32ビットの長語で表現される（図４）。メ
モリセルを長語境界に置き、下位２ビットをタグ、上位
30ビットをアドレスまたは数値とすることで、４Gbyte
のアドレス空間が確保される。タグは、00が整数、01が
浮動小数、10がポインタ、11は未使用を意味する。整数
は±109 のレンジを持ち、浮動小数の計算機エプシロン
は10-6程度となる。数値の長精度形式はない。このポイ
ンタ表現には次の特徴がある。
①整数の加減算では、タグを無視してよい。
②ポインタとして解釈する時は-2のオフセットを加えれ
　ばよく、タグをマスクする操作は不要である。
③ポインタが指すオブジェクトのクラスを表すためにオ
  ブジェクト側にタグを付ける必要がある。
④即値のレンジが広く、数値演算によってメモリを消費
　することがない。

3.2 オブジェクトの構造
　オブジェクトは、図５に示すのような１語のヘッダと
それに続く変数・要素で構成されるセルによって表現さ
れる。ヘッダのフィールドは次のような意味を持つ。
　bmgps:  メモリセル管理情報
　　b: buddy-bit
    m: memory-bit
    g:  ごみ集め用マーク
　　p,s:環状オブジェクトのプリント、コピー用マーク
　elmt: ベクタ要素型
　　0: non-vector 1: bit　  2: byte     3: char
    4: integer　  5: float  6: foreign  7: pointer
　bix: buddy-index（バディセルの大きさの指標）
　cid: class-id   （オブジェクトの属するクラスid）
　オブジェクトは、ベクタ型と非ベクタ型に分けられる
。ベクタ型は要素の数が可変であり、インデックスでア
クセスされる。非ベクタ型は要素（スロット）の数が固
定（クラスが定める）であり、スロット名でアクセスさ
れる。ベクタ型オブジェクトの場合は、ヘッダのelmtフ
ィールドが要素の型を表し、文字、整数、浮動小数など
に対しては効率的かつＣなどと互換性のある表現がとら
れる。ヘッダの次の語には要素の数を示す数値が入る。

3.3 メモリ管理
　メモリの管理手法は、Lispの柔軟性と効率に大きく影
響する。Euslisp では単一のヒープ上でのバディ法を用
いたメモリ管理を行なっている[5] 。バディ法を採用し
たのは、メモリの動的拡張を可能にするのと、コピーに
よる圧縮の必要性を除くためである。特に後者は、①コ
ンパイルドコードが他のオブジェクトと同一のヒープに
配置されること、②他言語プログラムとのリンクを図る
上でセルの番地が変化することは容認できないこと、③
ごみ集めの効率向上、④ごみ集めを抑制するためにユー
ザが消費したメモリを陽に返却する機能の実現、などの
要請に基づいている。ただし、参照が広い領域に散らば
るので、仮想記憶管理の負担は増加する。
　バディ法の基本アルゴリズムは次の様になる。
①メモリが要求されると大きなセルを分割し、要求を満
たす最小のセルを作成して返す、②ごみ集めによって不
要なセルが見つかると、その前後のバディセルを検査し
それらも不要なセルであれば併合する、可能ならば併合
を再帰的に繰り返し、より大きなセルにして回収する。
　分割と併合が簡単に処理できるよう、バディ法ではセ
ルの大きさを２のべき、フィボナッチ数などに制限する
。前者をバイナリバディ、後者をフィボナッチバディと
呼ぶ[4] 。どちらが適当であるかは、要求されるメモリ
サイズの分布に依存する。Euslisp で幾何モデラを走ら
せた場合、図６に示すようなメモリの要求が生じている
。これでわかるように、メモリ要求は３語（主にcons）
、６語（主に３次元float-vector）のセルが圧倒的に多
く、次のような考察に基づいてフィボナッチバディを採
用している。
　まずメモリ効率について考える。セルの大きさの種類
に制限があるためにセルの内部に生ずる無効領域を内部
ロス、セルが散在するために連続領域が取れなくなるこ
とによる無効領域を外部ロスと呼ぶ。フィボナッチバデ
ィはバイナリバディに比べて、外部ロスが大きいとされ
るが、要求・消費の多いconsセルのサイズが最小なので
外部ロスは０になる。内部ロスは、セルの大きさの種類
を増やすに従って減少する。フィボナッチの方がバイナ
リより多くのセルサイズを作れるので、PetersonとNor-
man[5]の解析では、バイナリ・バディの場合は約30% の
ロス、フィボナッチ・バディでは約22% の内部ロスが予
測されている。さらに、consセルの割合が多い性質を利
用して、consにぴったりの大きさのバディサイズを用意
しておけばこのロスをさらに低減できる。実測では、コ
ンパイルドコード（相対的に大きいセル）を除くと10%
程度のロスであることが確認された。これは、コピー法
による記憶管理での50% のロスに比べて非常に効率的な
値である。
　セルの大きさの種類は、3,3,6,9,15,24,39,63,112...
となっており、３０種類のセルサイズで最大16Mbyte ま
でのセルを実現している。最小のセルが３なのは、cons
がheader+car+cdrの３語で構成されるからである。
　バディ法とBIBOP 法を比べると、バディ法ではすべて
のページが平等で管理法が均質であり、異なった大きさ
のセルの間で融通がきくかわりに、メモリ割り当ての際
の分割、ごみ集めの際の併合の手間が余分にかかる。と
ころが、ごみ集めの後で要求されるセルはconsであるこ
とが多く、せっかく大きな連続領域に併合されたセルも
再び極限まで分割されることになる。この不合理を軽減
するため、メモリの一定量（５割程度）は併合をしない
で分割されるに任せておく。しばらくたつとその中はほ
とんどがconsで埋め尽くされ、consのための特別のペー
ジを用意しなくとも、効率的な割り当てが実現できる。
４．幾何モデリング
4.1 Lispと幾何モデラ
　幾何モデラとは、基本素立体の集合演算による３次元
物体の形状定義、移動・回転などの座標変換、属性の定
義と問い合わせ、表示などの機能を持ったソフトウェア
である。ロボットの環境認識、作業計画、動作の教示と
シミュレーションなどで幾何モデルは重要な役割を演ず
る[6] 。従来、幾何モデラはFortran で実現される例が
多かった。しかし、拡張性が低い、大きなモデルを扱え
ない、モデルデータへのアクセスが困難などの問題があ
り、ロボットシステムへの統合化が阻まれていた。
　これに対して幾何モデラをオブジェクト指向型Lispで
実現することの利点は次のようにまとめられる。
①モデル要素はオブジェクトで、位相関係はポインタに
　よって明確に表現できる
②オブジェクトによってモデルの振舞いが抽象化される
③クラスの継承を用いることで属性の追加が可能
④モデルの保存・通信（外部表現への変換）が容易
⑤メモリ管理から解放され容量的制限が無い
⑥特別のコマンド言語を作成する必要がない。
　Lispは数値計算には向かないとの意見もあるが、ベク
タ、マトリクスなどの幾何データとその演算プリミティ
ブを組み込み関数とし、コンパイラを利用すれば処理速
度の点でも大きな問題とはならない。プリミティブとし
て定型化できない処理の大部分はポインタ操作であり、
Lisp本来の機能によって簡潔に記述できる。

4.2 ベクタ・マトリクス演算と座標系
　幾何計算ではベクタ・マトリクスの演算が多く登場す
るので、Euslisp では浮動小数の１次元配列をフロート
ベクタ、浮動小数の２次元配列をマトリクスとして定義
し、それらの間の演算を行なう組み込み関数を多数用意
している。
　ベクタ演算関数には、和、差、内積、外積、スカラ３
重積などがある。マトリクス関数には積、変換、転置、
回転、等価回転軸の取り出し、LU分解による逆行列、行
列式などがある。また、行列の線型計算については、５
章で述べる他言語インタフェースによりlinpack 等の数
値計算ライブラリをリンクすることができ、固有値、特
異値分解などにも対応することができる。
　原点位置と回転マトリクスの組合せで座標系を表すた
めに、クラスcoordinates が用意されている。coordina
tes はワールド、ローカルあるいは任意の座標系で表現
された移動、回転、変換、逆変換などを受け付ける。さ
らに、階層的に結合された座標系を表現するクラスとし
てcascaded-coords がある。これによって多関節型のマ
ニピュレータや部品と部品を取り付ける操作等を簡単に
モデル化することができる。これらのcoordinates,casc
aded-coords は、視点を表すviewing,物体を表すbodyな
どのスーパクラスとして汎用的に用いられる。

4.3 オブジェクトによるモデル表現
　物体は多面体で近似され、Brep(Boundary-representa
tion) で表現される。edge,face,hole,body などのモデ
ル要素は、図７のような継承構造を持つクラスによって
階層的に定義される。vertex（頂点）は３次元フロート
ベクタで表される。オブジェクトのスロットの内容を図
８に示す。モデル要素の参照関係は再帰的になる。
　オブジェクトの状態に基づく計算法、状態の変更、機
能名は同じだが対象物によって意味が異なるアルゴリズ
ム（交点計算、点の内外判定など）はメソッドとして定
義している。一方、ｎ個の要素に対する対等な操作や新
たな要素を生成する操作（干渉検査、点列からの凸包の
生成など）は関数として実現している。
　Brepの表現法としては、Baumgartのウィングドエッジ
が有名である。しかし、ウィング（接続するエッジ）の
情報はfaceのエッジリストから、全エッジはbodyのエッ
ジリストから取り出すことができるので、エッジにはウ
ィングは登録しない。このため４つのスロットが節約さ
れ、エッジの管理が簡素化されている。faceがholeリス
トを余分に持つ以外、faceとholeはほぼ同じデータ構造
を持ち、共通するアルゴリズムはclosed-region に記述
されている。
　サブクラス定義による属性追加は容易である。たとえ
ば、ウィングを持ったエッジが必要であれば、edgeクラ
スの代わりにwinged-edge クラスを用いればよい。グロ
ーバル変数*edge-class*にwinged-edge をセットしてお
けば、以後生成されるエッジはwinged-edge のインスタ
ンスになる。同様に面にcolor 属性を付加したければ、
colored-faceをfaceのサブクラスとして定義すればよい
。
4.4 形状定義と合成操作
　形状は、素立体を元に和、差、積、反転、切断などの
集合演算を施すことで定義される。これらの操作はクラ
スに定義された交点計算メソッドを用いた関数として実
現されている。また、従来使用されてきたソリッドモデ
ラとの互換性を保つために、SOLVER[6] の内部表現をEu
slisp のオブジェクト構造に変換する方法も用意されて
いる。
　集合演算などの変形操作では、データ構造をトラバー
スしながら多くの交点計算、エッジセグメントの作成が
実行される。従来の幾何モデラには計算の途中結果をデ
ータ構造の中にマークとして残したり、ポインタを破壊
的に置換するものがあるが、Lispでは途中結果をリスト
につないでいく方法が取れるので、より安全で明確なア
ルゴリズムが実現できる。さらにcopy-object 関数によ
り再帰的参照関係を保存したセルのコピー法が実現され
ているので、非可逆的なモデル操作における状態の保存
・復帰が容易である。

4.5 属性計算
　形状オブジェクトに対しては、干渉検査、凸包の生成
（図9b）、断面図形の生成（図9c) などが実現されてい
る。さらに体積、重心などのマスプロパティが計算でき
る。これらはいずれもロボットの動作シミュレーション
や作業計画にとって重要である。たとえば重心と凸包を
用いれば物体の安定姿勢が算出可能であり、環境モデリ
ングの拘束条件に利用できる。

4.6 隠線処理、表示
　最近のグラフィックワークステーションは非常に高速
で隠面処理表示を行なうが、アプリケーションから表示
される面の情報にアクセスすることはできない。視覚認
識やスーパインポーズ表示のためにはソフトウェアによ
る隠線処理は依然として重要である。Euslisp の隠線処
理ルーチンは結果としてimage オブジェクトを生成し、
図形の領域、エッジ素片に対するシンボリックなアクセ
スが可能になる。image はSunview,Suncore,Xwindow 等
を利用して表示される[10]（図10）。

4.7 オブジェクトベース機能
　ソリッドモデリングによって作成されるデータ構造は
複雑な参照関係を持ち、作成に時間がかかるので保存の
必要がある。グラフィックス標準ではメタファイルが検
討されているが、拡張属性の入出力、再帰的参照関係の
復元は厄介な問題である。Euslisp では、#Sフォーマッ
トによるオブジェクトのread/print, #n=,#n# ラベルに
よる再帰参照の解決により、CommonLisp間で互換性のあ
る外部表現との相互の変換が可能である。これによりモ
デル、図形の簡便なデータベース化が達成できる。さら
に、計測、モデル生成、表示、計算などの作業を複数の
Euslisp で分担し、socket-stream を通じてモデルを送
受しあうような分散型のロボットモデルベースシステム
の構築が可能となる。
５．他言語インタフェースとウィンドウシステム
5.1 他言語インタフェース
　UNIX上ではLispだけですべてのプログラムを開発する
のは困難である。UNIXはＣ用のOSであり、UNIXに強く依
存する部分はＣで記述する方が簡潔に記述できるのと、
バイナリで供給されるライブラリやパッケージを利用す
る必要があるからである。そこで、Euslisp はＣやFort
ran で書かれたプログラムと双方向のリンケージを取る
手段を実現している。
　Euslisp のカーネルはＣで記述されている。また、Eu
slisp コンパイラはLispソースをＣに変換する。したが
って基本的にEuslisp とＣはよく親和する。Euslisp コ
ンパイラの生成するＣプログラムと、通常のＣプログラ
ムとの主な違いは、①関数のシンボルへの登録（初期化
）、②引数と結果の型変換、の２点にある。①はdeffor
eignによってロード時に、②はfuncall によって実行時
に解決される。
　Euslisp がコンパイルしたプログラムはloadによって
読み込まれ、compiled-code のインスタンスが作られる
と共にプログラム中の初期化ルーチンが実行されるのに
対し、一般のＣプログラムはload-foreignによって読み
込まれ、単にforeign-moduleのインスタンスが作成され
る。foreign-moduleはcompiled-code のサブクラスであ
り、codeとしての性質の他に、モジュール中の外部シン
ボル表を属性に持っている。このシンボル表を参照して
、defforeignマクロがLispからＣ関数へのエントリを付
ける。defforeignには、外部関数のパラメタと結果の型
を指定する。Lispのdefun がシンボルにcompiled-code
オブジェクトを登録するのに対し、defforeignはシンボ
ルにforeign-codeを登録する。foreign-codeはやはりco
mpiled-code のサブクラスであり、関数へのエントリ番
地のほか、パラメタと結果の型が記憶される。
  funcall は、コードオブジェクトの型を見て、foreig
n-codeであれば、引数をLispのポインタからＣの要求す
る型に変換する。実際は、Lispのポインタからは実行時
に型の情報が抽出できるので、defforeignの引数の型指
定は省略できる。Ｃから返される値の型は常に不明なの
で、結果型の情報は省略できない。型変換に当たって、
Euslisp のstring,integer-vector,float-vectorの内容
表現はＣやFortran での表現に近いので、変換のオーバ
ヘッドは僅かである。図10に、Ｃのプログラムをロード
し、エントリを定義し、実行する例を示す。
　ＣからEuslisp の関数を呼び出せるようにするために
は、次のdefun-c-callableマクロを用いる。
 (defun-c-callable　funcname
  　 ({(param type)}*)  result-type 　. body)
　defun-c-callableは、symbolのサブクラスであるfore
ign-symbolのインスタンスを作成する。foreign-symbol
には、Lispの関数としての属性の他に、Ｃから呼ばれた
場合にＣからLispへの引数の変換を行なうルーチンに分
岐する機械語列と、引数と結果の型の情報が格納されて
いる。この機械語列の番地をＣプログラムに知らせてお
けば、ＣからLisp関数を呼び出すことができる。defun-
c-callableの機能は、ウィンドウサーバから送られて来
るマウスのイベント処理などに必要となる。
　LispからＣのstructへアクセスするためにcstruct ク
ラスがある。cstruct は、stringのサブクラスとしてde
fcstructマクロによって定義される。さらにＣがmalloc
等で確保したメモリにLisp側からアクセスできるよう、
stringのサブクラスにforeign-stringがある。foreign-
stringはLispからはベクタとして扱われるが、実体はLi
spのメモリ空間外に取られることになる。

5.2 ライブラリのリンク
　他言語インタフェースが威力を発揮するのは、linpac
k,eispack などの数値計算パッケージや、Xwindow,Sunv
iew などのウィンドウシステムを利用する場合である。
これらのライブラリは非常に多くの関数を定義している
ので、Ｃでインタフェースを書き下すよりは、他言語イ
ンタフェースを利用する方がはるかに簡便である。ただ
し、いくつかの制約が加わる。
　linpack は元来Fortran 用なので、パラメタの渡し方
がcall-by-reference である。このため、整数、浮動小
数の即値を渡す場合にはいったんベクタに値を格納しな
ければならない。また、Sunview はかなりの機能を関数
ではなくマクロで供給しており、ユーザはマクロを使っ
た関数を別に定義する必要がある。Xwindow にはマクロ
と関数の両方の定義があるので、このような手間は皆無
である。単にXlibをリンクするだけで、400 近いXlib関
数がLispから利用可能になる。この方法は、CLX のよう
なＸのプロトコルをLispで実装する方法に比べて、Xlib
の改変に強く、効率も劣化しないという利点がある。

5.3 ウィンドウシステム・インタフェース
　Euslisp 上にXwindow,Sunview,環境を構築した。Ｘで
は,drawable,window,pixmap,graphic-context などをク
ラスとして定義している。Sunview では window,frame,
canvas, panel, tty, button, slider,menu など18個の
クラスを定義している。各々のオブジェクトには、マウ
スのクリックやメニュの選択によって非同期に実行され
るメソッドが、defun-c-callableによって登録される。
この非同期処理によって１つのEuslisp プロセスに複数
のウィンドウから並列に指令を出すことができ、良好な
ユーザインタフェースが構成できることが確認できた。
図11は、Sunview を用いたロボットビジョンシステムの
ユーザインタフェースの表示である。
　これらのクラスおよびテクトロ端末用のview-surface
クラスを適当に選ぶことで、上位のソフトウェアに手を
入れることなく、多くの描画用ハード・ソフトに対応で
きるようになっている。これもオブジェクト指向の利点
の１つである。


６．まとめ
　ロボットプログラミングの核となる言語、Euslisp の
オブジェクト指向に基づくインプリメンテーション、幾
何モデラ、他言語インタフェースを用いたウィンドウシ
ステムとの結合について述べた。クラスの継承により、
システムの機能を拡張する形で、多くの機能を簡単に実
現することができた。
　Lispとしての性能はインタプリタではKCL より数10%
高速であり、コンパイルドコードではKCL と同程度であ
る。幾何計算の関数が多数用意されているので、幾何モ
デラとしての効率はSOLVER等と遜色ない。幾何モデラ部
分のプログラム量は千数百行であり、１人月程度で開発
できた。モデルのデータ量に制約がない点、モデルの情
報にアクセスできる点により、オブジェクト指向による
高い拡張性を有する点などから、高次のロボットプログ
ラミングに応用できると考えられる。EUSlisp は現在su
n3,sun4,News,vax/ultrix などで稼働中であり、ソース
コード付きで公開されている。

謝辞　本研究を支援下さった、電子技術総合研究所、弓
場敏嗣知能システム部長、柿倉正義自律システム研究室
長、高瀬国克行動知能研究室長に感謝致します。また貴
重なご意見をお寄せ下さった電総研、東京大学、神戸大
学、三洋電機のEuslisp ユーザの皆様に感謝致します。

参考文献
[1] Steel Jr.,G.L.: "Common Lisp  the  Language,"
    Digital-Press,(1984).
[2] Lang,K.J.  and  B.A. Pearlmutter: "Oaklisp: An
  　Object-Oriented Scheme with First Class Types"
　　OOPSLA,(1986)
[3] Bobrow,D.G.,et al: "CommonLoops: Merging  Lisp
　　and Object-Oriented Programming,"OOPSLA,(1986)
[4] Cranson,B. and R.Thomas:"A Simplified Recombi-
    nation Scheme for the Fibonacci Buddy System,"
    CACM, vol.18, no.6, (1975).
[5] Peterson,J.L. and T.A.Norman:"Buddy Systems,"
    CACM, vol.20, no.6, (1977).
[6] Koshikawa,Shirai:"A 3-D Modeler for Vision Re-
    search,"　Proc. of Int. Conf. Advanced Robots,
    (1985).
[7] 松井、他：「Lisp上の対象指向型プログラミング機
    能LEO 」、電総研彙報、vol.49,no.7,(1985).
[8] 松井、塚本：「Euslisp:対象指向による型拡張性を
    有するLispの実現」、情報処理学会第35回全国大会
    (1987).
[9] 松井、稲葉：「対象指向型Lisp:Euslispを用いたロ
　　ボット用幾何モデリングシステム」、情報処理学会
　　第37回全国大会、(1988).
[10]稲葉、松井：「対象指向型Lisp:EUSlispの他言語イ
　　ンタフェースとウィンドウシステムへの応用」、情
　　報処理学会第37回全国大会、(1988).
