[English page is here]
このソフトウェアは,独立した2つのソフトウェアから構成されています.

(1) parade (PARallel Active Database Engine) :

並列アクティブデータベースプロトタイプ

(2) fatpas (FAult Tolerant PArallel Software) :

耐故障並列ソフトウェアライブラリ

このプログラムは、さらに次の二つから構成されています。

(2-1) expand : KLICマクロ展開プログラム

(2-2) fts : 耐故障並列ソフトウェアライブラリ


【並列アクティブデータベースエンジン: Parade】


by

横田治夫 at JAIST (北陸先端科学技術大学院大学)



[用途]

広範囲のデータベース処理を前提にしており、動的な経営判断や株の 動向解析といったビジネス分野も対象にしているが、現バージョンは まだ必ずしも安定していないため、実験的利用が望ましいと思われる。 サーバーの関係代数レベルのストリームインタフェースは、KLIC で 書かれたアプリケーションプログラムに対してデータベース利用をサ ポートする。

[機能]

用意されたアクティブルールによって能動的にデータベースの内容を チェックして条件を判断し、定められた動作を行うことを目標に作ら れており、以下の機能を持つ。

[実行環境]

以下のマシン上とKLIC version 2.002の組み合わせ

[ファイル構成]

parade/
COPYRIGHT
Readme-E.html
Readme-J.txt
advertise-E.html
advertise-J.html
rdbhosts
Makefile
common/
client/
sqlclt/
dict.kl1
hostname.kl1
parser.kl1
sqlclt.kl1
uif.kl1
oqlclt/
hostname.kl1
paraio.kl1
uif.kl1
dict.kl1
oqlclt.kl1
parser.kl1
server/
access.kl1
access1.kl1
algebra.kl1
create.kl1
deadlock.kl1
delete.kl1
drop.kl1
exec.kl1
insert.kl1
lock.kl1
log.kl1
node_io.kl1
processor.kl1
projection.kl1
rdbserv.kl1
selection.kl1
trans.kl1
rule.kl1
btree/
bt_add.kl1
bt_del.kl1
bt_del1.kl1
bt_del2.kl1
bt_del3.kl1
bt_get.kl1
bt_name.kl1
bt_page.kl1
bt_pagename.kl1
bt_util.kl1
btinit.dat
btree.kl1
coding/
Makefile
decoder.kl1
encoder.kl1
fastio.kl1
util/
Makefile
util.kl1
rel/
Makefile
attributes
audit
dept
emp
faculty
relations.skel
nrelations.skel
rule
newrel/
doc/
catalogue.tex
papers.tex
parade_doc.tex
sun/
client/
sqlclt/
Makefile
oqlclt/
Makefile
javaQBE/
readme
index.html
makefile
DropPanel.java
ScrollableTable.java
GroupTable.java
SelectPanel.java
Attribute.java
QbePanel.java
Tag.java
AttributePanel.java
QbeSettingPanel.java
TagTable.java
AttributeTable.java
QueryAttributes.java
VStackLayout.java
QueryCreate.java
Client.java
QueryData.java
Communicate.java
QueryDelete.java
Const.java
QueryDrop.java
CreatePanel.java
QueryInsert.java
server/
Makefile
catalog.kl1
socket/
paraio.kl1
socket.kl1
ncube/
client/
Makefile
server/
Makefile
catalog.kl1
socket/
paraio.kl1
socket.kl1

[その他]

現在、開発途上です。

【KLICマクロ展開プログラム】


by

杉野栄二、横田治夫 at JAIST (北陸先端科学技術大学院大学)



[用途]

KL1ソースプログラムに対して加工を行ないたいときに、じゃまになる KLICのマクロ表記をとりのぞきたいとき、 またKLICで記述されたプログラムをPIMへ移植したいときにも役立つ。 あるいは、KLICで記述されたマクロが どのように展開されるかを 確かめたいときに有効である。

[機能]

本プログラムは、KLICにおけるマクロ表記等を含むKL1プログラムを ほぼプレーンなKL1プログラムに変換し、標準出力へ出力する。

[実行環境]

[ファイル構成]

fatpas/
expand/
README.j
README-j.html
README.e
README-e.html
Makefile
diff.kl1
kl1cmp.kl1
kl1cmp0.kl1
macro.kl1
main.kl1
obj.kl1
util.kl1
write.kl1
difftest
test

[インストール方法]

必要に応じてMakefile を修正し、

make all で実行形式 kl1expand が作られる。

[使い方] 変換結果は、標準出力に出力される。

その1)ファイルから入力する場合

% kl1expand File1 File2 ...
入力ファイル名は、***.kl1 の形であること。

その2)標準入力から入力する場合

% cat hogehoge.kl1 | kl1expand user
入力ファイル名として 'user' を指定すれば、標準入力からプログラムを 読み込む。

[変換後のプログラムについて]

  • KLICのコンパイラを元にしているため、ガードのOR
    head :- (guard1 ; guard2) | body.
    の形はそのまま出力する。 ・ モジュール宣言以下のコマンド

    :- xxxxx.

    は、モジュール内の述語定義の一番最後にまとめて出力される。

    ・ モジュール宣言前のコマンドは、モジュール宣言の前に出力される。

    [KLICのバージョンアップに対応するヒント]

    本プログラム対応版のKLICコンパイラ(compilerディレクトリ以下の *.kl1)を、 新版のコンパイラと比較して、それに対応するプログラムを変更する。
    KLICのバージョンアップに対応するために、ファイル名モジュール名等 できるだけ保存するようにしてある。
    対応するオリジナルのファイルとの共通部分の比較機能

    % make cmp

    も提供する。本プログラムの相違部分には、% IGNORE ... 等のコメントがあるが、 この比較機能はこの部分だけ無視して比較を行なうため、共通部分に変更が あれば、この機能でわかる。

    [試験]

    本プログラム自身を展開した結果とオリジナルプログラムに対して、 klicでコンパイルした結果で比較した。

    試験方法

    % kl1expand XXX.kl1 > tmp.kl1
    % klic -c XXX.kl1 tmp.kl1
    % cmp XXX.c tmp.c

    試験結果

    • main.kl1 ○
    • write.kl1 ○
    • util.kl1 △
    • obj.kl1 △
    • macro.kl1 △
    • kl1cmp.kl1 ×
    ○は一致したもの、
    △はkl1cmp.kl1 中の tidy_clause を行なわないと一致する。

    tidy_clauseは、変数名のつけかえ等を行なって 結果クローズの見栄えを良くするものである。 このため、変数の割り付け方が変わるものと思われる。

    kl1cmp.kl1 のかわりに kl1cmp0.kl1を用いてコンパイルすると tidy_clauseを行わない結果が得られる。

    ×は、述語のコンパイル順序が変わることによる。

    クローズ内のif-then 表記マクロの展開によって、新たに生成 される述語の順序が オリジナルのコンパイラでは逆順になっている。 このため、内部で生成するテーブル、ラベル名等の割り付けが 異る。


    変更履歴:

    • klic (limited release version 2.004) コンパイラをもとに作成。 [Version 1.0] 1996.10.25 by 杉野栄二 (sugino@jaist.ac.jp) ただし、klic (version 3.001)での動作を確認(1997.7.30) 。
    • 1996.10.31 プリティプリントを変更
      • orゴールの表記に段下げをつけた。
      • ボディ変数と非変数のボディユニファイが 出ないようにした。(変数を非変数に置き換える)
    • 1996.12.19 プリティプリントを修正 ボディで冗長なユニフィケーションが出ていたため。
    • 1997.02.28 ガード組み込み述語の演算部分の表記を修正 (divide(A,B,C) -> C := A/B 等)

    【耐故障並列ソフトウェアライブラリ】


    by

    杉野栄二、横田治夫 at JAIST (北陸先端科学技術大学院大学)



    [用途]

    一般の並列計算機上で、KL1プログラムの耐故障実行を実現する。

    [機能]

    サンプルプログラム ft_queen.kl1 のように 耐故障ソフトウェア化したKL1プログラムとリンクすることで、 耐故障実行を行う。

    述語 distribution(Primary,Backup) : watchdog.kl1 で提供される

    は、すべてのノードを二つに分け、それぞれで監視プロセス起動する。 それぞれのプロセスへのストリームをリストにしてPrimary, Backup へ返す。

    述語 copy(Args,Args1,Args2,Interrupt) : copy.kl1 で提供される

    は、与えられた引数(変数を含む)Argsを複製し、Args1, Args2へ返す。 変数に対してはそれぞれプロセスが生成される、Argsの変数に 動的にユニファイされる値に対しては、対応するArgs1,Args2の変数に ブロードキャストされる。 逆にArgs1, Args2へは同じ値がユニファイされる ものとし、そのいずれかをArgsの対応する変数へ送る。 変数に対して生成されているプロセスは、 ストリーム Interruptへ fault が送られると ArgsとArgs2とをユニファイして 終了する。

    [使い方]

    ライブラリ watchdog.kl1、copy.kl1 および、 使用する環境に応じてncube.kl1 または sparc.kl1 、 それとユーザプログラム (サンプルプログラムならば main.kl1 と ft_queen.kl1 ) をKLICでコンパイル、リンクして起動する。

    % klic -v -dp -o dofts watchdog.kl1 copy.kl1 sparc.kl1 main.kl1 ft_queen.kl1
    注)使用可能なノード数の総数が3個以上なければならない。

    [実行環境]

    • KLIC klic version 2.002
    • nCUBE2:nCX 5.105a 3.4.0 または
    • SunOS 4.1.3

    [ファイル構成]

    fatpas/
    fts/
    README.j
    % 日本語版 README
    README-j.html
    % 本ファイル
    README.e
    % 英語版 README
    README-e.html
    % 英語版 html
    watchdog.kl1
    % 監視プロセス
    copy.kl1
    % プロセス複製
    ncube.kl1
    % nCUBE2向けライブラリ
    sparc.kl1
    % SPARC向けライブラリ
    === サンプルプログラム ===
    main.kl1
    % サンプルプログラム 主ルーチン
    queen.kl1
    % N-Queenプログラム
    ft_queen.kl1
    % 耐故障化 N-Queenプログラム
    ft_queen_faulty.kl1
    % 耐故障化 N-Queenプログラム エラーあり
    main-sim.kl1
    % サンプルプログラム(その2)主ルーチン
    f_sim.kl1
    % サンプルプログラム(その2)
    f_sim_faulty.kl1
    % サンプルプログラム(その2)エラーあり

    [実行例]

    分散版KLICのトレース機能が利用できないため、バグが完全に とりきれていない。 よって現在の版では、故障に対して完全に 実行継続できない。 サンプルプログラム(その2)については、ある程度の 継続動作が見られる。

    1) コンパイル

    % make sparc

    2) エラー無しの実行

    % ./dofts-s -p5 10 100d
    Leader [1]
    Leader [2]
    Backup Site Group : 2 4
    Primary Site Group : 1 3
    30 [67,1]
    <== プログラム出力 A (30), B ([67,1])
    Response time is 1359 msec

    3) エラーありの実行

    amethyst[300]% ./dofts-sf -p5 10 100d
    Leader [1]
    Leader [2]
    Primary Site Group : 1 3
    Backup Site Group : 2 4
    BOMB! 3
    <== Node 3 でexit
    30 FAULT was detected on PRIMARY SITE!
    <== 出力 A の後、故障検出
    FAULT was informed to BACKUP!
    BACKUP change to PRIMARY !!! REBIRTH (1) [4]
    REBIRTH (2) [4]
    ... REBIRTH ndet_replay [117,1]
    <== 内部メッセージの後、出力 B
    ^Ckill tasks from io_server
    <== 正常終了しないため ^C

    耐故障化変換 プログラムは、未完成であるので、以下に耐故障化変換の指針を記す。

    [耐故障化の指針]

    1) 耐故障実行させたい部分を分離する。

    ユーザプログラムは、main.kl1 と queen.kl1 に分離されており、 述語 queen:queen(N,Result) を耐故障実行する。
    注) オリジナルのプログラムは、main.kl1 queen.kl1 だけで動作する。

    2)耐故障実行させたい部分を次の手順で変更する。

    2-1) 呼び出される一番上の述語を次の例のように変更する。

    % オリジナルの述語呼び出し
    queen(N,R) :-
    % 監視プロセス生成
    watchdog:distribution(Primary,Backup),
    % 次の述語へ引数を渡す
    queen_1({N,R},Primary,Backup) @ lower_priority(10).
    % プライマリとバックアップの主プロセスへのストリームを取り
    queen_1(Args,[PTop|Primary],[BTop|Backup]) :-
    % 引数を複製し、
    copy:copy(Args,Args1,Args2,Interrupt),
    % 割り込み線をマージし、
    Interrupt = {Interrupt1,Interrupt2}, Log = ack(Log1),
    % プライマリ、バックアップそれぞれへ
    % トップのゴールをフォークする
    PTop = {primary,queen,queen,Args1,Log,Signal,Interrupt1},
    BTop = {backup ,queen,queen,Args2,Log1,Signal,Interrupt2}.

    2-2) トップゴールの呼び出し口を用意する。

    呼び出し口は、モジュール exgoal に定義される。
    上では、モジュール queen の述語 queen は、オリジナルのアリティが2 となっているので、以下の =-=-=-=- の間の2クローズが定義される。
    :- module exgoal.
    call_goal(Site,Module,Predicate,Args,Log,GSig,Raise)-SC :-
    call_goal_0(Site,Module,Predicate,Args,Log,GSig,Raise)-SC @ lower_priority.
    % =-=-=-=-
    call_goal_0(primary,queen,queen,{A,B},Log,GSig,Raise)-SC :-
    queen:queen_record(A,B,Log)+GSig+Raise-SC.
    call_goal_0(backup ,queen,queen,{A,B},Log,GSig,Raise)-SC :-
    queen:queen_replay(A,B,Log)+GSig+Raise-SC.
    % =-=-=-=-
    otherwise.
    call_goal_0(Type,Module,Method,Arguments,Log,GSignal,Raise)-SC :-
    klicio:klicio([stdout(normal(Out))]),
    variable:wrap((Type::Module:Method/Arguments), G),
    Out = [fwrite("Illegal goal invocation : "), putwt(G), nl,fflush(_)],
    Raise = [].

    2-3) 2-3 で定義した トップゴール に対応する述語を用意する。

    (1) もとの述語に対して Instant Replay 変換する

    % Record Version
    queen_record(N,X,Log) :-
    current_node(_,All),
    queen_0_record(N,X,~(All-1),Log)@node(1).
    queen_0_record(4,X,A,Log) :- queen_record([1,2,3,4],[],[],X,A,Log).
    ....
    queen_record([P|U],C,L,I,PE,Log) :-
    Log = c1(Log1,Log2,Log3),
    TO:= (P mod PE)+1,
    throw_record(U,[P|C],L,I2,PE,TO,Log1),
    merge_record(I1,I2,I,Log2),
    append(U,C,N),
    c1_record(P,1,N,L,L,I1,PE,Log3).
    % Replay Version
    queen_replay(N,X,Log) :-
    current_node(_,All),
    queen_0_replay(N,X,~(All-1),Log)@node(1).
    queen_0_replay(4,X,A,Log) :- queen_replay([1,2,3,4],[],[],X,A,Log).
    ....
    queen_replay([P|U],C,L,I,PE,Log) :-
    Log = c1(Log1,Log2,Log3) |
    TO:= (P mod PE)+1,
    throw_replay(U,[P|C],L,I2,PE,TO,Log1),
    merge_replay(I1,I2,I,Log2),
    append(U,C,N),
    c1_replay(P,1,N,L,L,I1,PE,Log3).

    (2) すべてのユーザ述語について引数を追加する

    引数GSigは上位からの割り込み用であり、全ゴールにブロードキャストされる ように、サブゴールにそのまま渡す。
    引数Raiseはゴールからの割り出し用なので、サブゴールが複数あるような 場合には、mergeされるようにサブゴールのRaiseストリームから成る ベクタをユニファイする。 サブゴールが一つだけなら、そのまま渡す。 サブゴールが存在しなければ、 [] とユニファイする。
    引数組 SC は、ショートサーキットするだけのためなので、そのまま各ゴール につけるだけである。
    % Record Version
    queen_record(N,X,Log)+GSig+Raise-SC :-
    current_node(_,All),
    queen_0_record(N,X,~(All-1),Log)+GSig+Raise-SC @node(1).
    queen_0_record(4,X,A,Log)+GSig+Raise-SC :-
    queen_record([1,2,3,4],[],[],X,A,Log)+GSig+Raise-SC.
    ....
    queen_record([P|U],C,L,I,PE,Log)+GSig+Raise-SC :-
    Raise = {Raise1,Raise2,Raise3,Raise4},
    Log = c1(Log1,Log2,Log3),
    TO:= (P mod PE)+1,
    throw_record(U,[P|C],L,I2,PE,TO,Log1)+GSig+Raise1-SC,
    merge_record(I1,I2,I,Log2)+GSig+Raise2-SC,
    append_record(U,C,N)+GSig+Raise3-SC,
    c1_record(P,1,N,L,L,I1,PE,Log3)+GSig+Raise4-SC.

    (3) Record Versionでは、非決定的述語で Logのack待ち部分を挿入する

    queen_record([P|U],C,L,I,PE,ack(Log))+GSig+Raise-SC :-
    Raise = {Raise1,Raise2,Raise3,Raise4},
    Log = c1(Log1,Log2,Log3),
    TO:= (P mod PE)+1,
    throw_record(U,[P|C],L,I2,PE,TO,Log1)+GSig+Raise1-SC,
    merge_record(I1,I2,I,Log2)+GSig+Raise2-SC,
    append_record(U,C,N)+GSig+Raise3-SC,
    c1_record(P,1,N,L,L,I1,PE,Log3)+GSig+Raise4-SC.
    queen_record([],[_|_],_,I,ack(Log))+Sig+Raise-SC:-
    Raise=[],
    Log=c2(Ack),
    I=[].

    (4) Record Version では、非決定的述語で ボディユニファイのところに ack待ちを挿入する (出力コミット)

    queen_record([],[_|_],_,I,ack(Log))+Sig+Raise-SC:-
    Raise=[],
    Log=c2(Ack),
    output(Ack,I, [])-SC.
    output(Ack,X,Y)-SC :- wait(Ack) | X = Y.

    (5) Replay Version では各述語の前に 割り込みチェック処理用の クローズを挿入する

    % Replay Version
    queen_replay(A, B, Log)+GSig+Raise-SC :-
    (wait(Log) -> queen_replay_0(A, B, Log)+GSig+Raise-SC ;
    alternatively;
    GSig = [rebirth|GSig1] -> queen_record(A, B, _)+GSig1+Raise-SC).
    queen_replay_0(N,X,Log)+GSig+Raise-SC :-
    current_node(_,All),
    queen_0_replay(N,X,~(All-1),Log)+GSig+Raise-SC @node(1).
    queen_0_replay( 4,X,A,Log)+GSig+Raise-SC :-
    queen_replay([1,2,3,4],[],[],X,A,Log)+GSig+Raise-SC.
    ....
    queen_record([P|U],C,L,I,PE,Log)+GSig+Raise-SC :-
    Log = c1(Log1,Log2,Log3) |
    Raise = {Raise1,Raise2,Raise3,Raise4},
    TO:= (P mod PE)+1,
    throw_replay(U,[P|C],L,I2,PE,TO,Log1)+GSig+Raise1-SC,
    merge_replay(I1,I2,I,Log2)+GSig+Raise2-SC,
    append_replay(U,C,N)+GSig+Raise3-SC,
    c1_replay(P,1,N,L,L,I1,PE,Log3)+GSig+Raise4-SC.
    queen_replay([],[_|_],_,I,ack(Log))+Sig+Raise-SC:-
    Log=c2(Ack) |
    Raise=[],
    I=[].

    (6) throw goal ('goal @ node(N)')は、すべて次のような割り出しに変える

    throw_record(A,B,C,D,E,F,Log)+GSig+Raise-SC :-
    Raise = [goal(primary,queen,queen,{A,B,C,D,E},Log)].
    throw_replay(A,B,C,D,E,F,Log)+GSig+Raise-SC :-
    Raise = [goal(primary,queen,queen,{A,B,C,D,E},Log)].
    現在のバージョンでは、隣のノードへ勝手に投げるのでノード番号は 必要ない。

    (7) throw goalするゴールに対応する入口を モジュールexgoalに追加する。

    call_goal_0(primary,queen,queen,{A,B,C,D,E},Log,GSig,Raise)-SC :-
    queen:queen_record(A,B,C,D,E,Log)+GSig+Raise-SC.
    call_goal_0(backup ,queen,queen,{A,B,C,D,E},Log,GSig,Raise)-SC :-
    queen:queen_replay(A,B,C,D,E,Log)+GSig+Raise-SC.
    ....
    otherwise.
    call_goal_0(Type,Module,Method,Arguments,Log,GSignal,Raise)-SC :-
    klicio:klicio([stdout(normal(Out))]),
    variable:wrap((Type::Module:Method/Arguments), G),
    Out = [fwrite("Illegal goal invocation : "), putwt(G), nl,fflush(_)],
    Raise = [].
    注)ft_queen.kl1 は、throw goalするゴールをc1に変え、 その他不必要な部分をオプティマイズしたものである。

    [FTP]

    • プログラムとドキュメント [160KB]


    www-admin@icot.or.jp