多重世界機構、実装の試み

#はじめに
中島秀之先生の考案した多重世界機構について標準エディンバラPrologに実装することについて実験的に試みました。


#多重世界機構とは
中島秀之先生がProlog/KRにおいて実装したものです。知識をPrologで表現するという研究の中で独自拡張として考案されました。詳細は下記の論文をお読みください。
「多重世界機構とその論理的意味」
https://ci.nii.ac.jp/els/contentscinii_20180819115008.pdf?id=ART0004920860

#実行例１

with/2述語は第１項が世界を表し、その世界において第２項の事実あるいは規則が存在することを意味しています。
下記は「知識表現とProlog/KR」p106にある例です。

```prolog

:- with(a,assertz(p(a))).
:- with(b,assertz(p(b))).
:- with(c,assertz(p(c1))).
:- with(c,assertz(p(c2))).

| ?- with(a,with(b,with(c,p(X)))).
X = c1;
X = c2;
X = b;
X = a;
no
| 

```

最も内側の世界から実行されていきます。


#実行例2

中島先生の論文にある例です。カナリアとペンギンは鳥です。鳥は空を飛びます。しかしながら、ペンギンは空を飛びません。denyは否定を表しています。

```prolog

:- with(w1,assertz(bird(canary))).
:- with(w1,assertz(bird(penguin))).
:- with(w2,assertz((fly(X) :- bird(X)))).
:- with(w3,deny(fly(penguin))).

| ?- with(w1,with(w2,with(w3,fly(canary)))).
yes
| ?- with(w1,with(w2,with(w3,fly(penguin)))).
no
| 
```



#実装のアイディア
事実あるいは節の頭部に世界を表す項を追加することによりそれが属する世界を表しています。add_worldが担当しています。

bird(canary)はw1世界で成り立つ事実なので bird(w1,canary) としています。
withで質問をすると、まずは動的に成立した世界をリストにします。[w3,w2,w1] のようにです。内側世界から実行されますのでこのようになっています。

withはwith1でその動的世界をリストに取りまとめた後に、call_withに回ります。組込述語はそのままですが、ユーザー定義の述語、節の場合には第1項に世界をしめす無名変数を追加して実行可能かどうかを探索しています。

#コード
かなり雑なコードです。考え漏れも多々あろうかと思います。ご容赦ください。

```prolog

%multiple world system

with(W,assertz(X)) :-
    add_world(X,W,Y),
    assertz(Y).
with(W,deny(X)) :-
    add_world(X,W,Y),
    assertz(deny(Y)).

with(W,with(X,Y)) :-
    with1(with(X,Y),[W]).
with(W,X) :-
    add_world(X,W,X1),!,
    call_with(X1,[W]).

with1(with(W,X),L) :-
    with1(X,[W|L]).
with1(X,L) :-
    add_world(X,_,X1),!,
    call_with(X1,L).

add_world(X,W,X) :-
    predicate_property(X,built_in).

add_world(X,W,Y) :-
    predicate_property(X,dynamic),
    X =.. X1,
    add_world1(X1,W,L),
    Y =.. L.

add_world((H :- B),W,(H1 :- B1)) :-
    add_world(H,W,H1),
    add_world_body(B,W,H,B1).

add_world((B1,B2),W,(C1,C2)) :-
    add_world1(B1,W,C1),
    add_world(B2,W,C2).

add_world((B1;B2),W,(C1;C2)) :-
    add_world1(B1,W,C2),
    add_world(B2,W,C2).

add_world(P,W,P1) :-
    P =.. L,
    add_world1(L,W,L1),
    P1 =.. L1.

add_world1([L|Ls],W,[L,W|Ls]).


add_world_body((B1,B2),W,H,(B1,C2)) :-
    predicate_property(B1,built_in),
    add_world_body(B2,W,H,C2).

add_world_body((B1,B2),W,H,(C1,C2)) :-
    functor(B1,H1,A1),
    functor(H,H1,A1),
    add_world(B1,W,C1),
    add_world_body(B2,W,H,C2).

add_world_body((B1,B2),W,H,(C1,C2)) :-
    add_world1(B1,W,C1),
    add_world_body(B2,W,H,C2).

add_world_body(P,W,H,P1) :-
    functor(P,H1,A1),
    functor(H,H1,A1),
    add_world1(P,W,P1).

add_world_body(P,W,H,P1) :-
    add_world(P,_,P1).

call_with((X,Y),L) :-
    arg(1,X,W),
    member(W,L),
    call(X),
    call_with(Y,L).

call_with((X;Y),L) :-
    arg(1,X,W),
    member(W,L),
    call(X),!.

call_with((X;Y),L) :-
    arg(1,Y,W),
    member(W,L),
    call(Y).

call_with(X,L) :-
    predicate_property(X,built_int),
    call(X).

call_with(X,L) :-
    predicate_property(X,dynamic),
    arg(1,X,W),
    member(W,L),
    deny(X),!,
    fail.

call_with(X,L) :-
    predicate_property(X,dynamic),
    arg(1,X,W),
    member(W,L),
    clause(X,true).
    

call_with(X,L) :-
    predicate_property(X,dynamic),
    arg(1,X,W),
    member(W,L),
    clause(X,Y),
    Y \= true,
    call_with(Y,L).



```

#参考文献
「知識表現とProlog/KR」　中島秀之　著　産業図書
「多重世界機構とその論理的意味」　中島秀之　著