飯高先生の本
「Prologで作る数学の世界」(飯高茂 著)をもとにしてN-Prologで位相計算をしていました。いくつかバグ、仕様不適合を潰しつつ位相空間の計算ができるようになりました。ご紹介します。
位相空間の定義
P152より引用
P(X)をXの部分集合全体の作る集合とする。これをXのべき集合という。P(X)の部分集合Oが次の条件を満たすとする。
1) 空集合と集合XはOに属する。
2) Oに属する集合たちの和集合はOに属する。
3) Oに属する有限個の集合たちの共通部分はOに属する。
このときOに属するXの集合を開集合という。XにOを合わせて考え、これを位相空間という。
べき集合
まずはべき集合を求める述語が必要です。
%p153
power0(Power1,Set) :-
bagof(X,(X isl subset(Set)),Power0),
sort(Power0,Power),
Power1 isl Power - [[],Set].
%p148
Y isl subset([A|X]) :-
memberd(A,Y),
Y0 isl Y / A,
Y0 isl subset(X).
Y isl subset([A|X]) :-
Y isl subset(X).
[] isl subset([]).
飯高先生は中置記法の方がお好きみたいでislというユーザー定義オペーレーターで部分集合を定義しています。それを使ってbagofに部分集合を集積することによりべき集合を計算しています。
開集合
和集合と積集合を求める述語を使って次のようにして開集合になるものを抽出しています。
%p154
topology_c(U,V,O) :-
(Z isl U+V,sort(Z,Zs), memberd(Za,O)),
(Z1 isl U*V,sort(Z1,Z1s),memberd(Z1s,O)).
%p100
memberd(X,L) :- member(X,L),!.
%p143
:- op(700,xfx,isl).
Y isl [] + Y :-!.
Z isl [A|X] + Y :-
memberd(A,Y),!,Z isl X + Y.
[A|Z] isl [A|X] + Y :- Z isl X + Y.
%p144
[] isl [] * Y :-!.
[A|Z] isl [A|Z] * Y :-
memberd(A, X),!,Z isl X * Y.
Z isl [A|X] * Y :- Z isl X * Y.
%p147
[] isl [] - A :- !.
Z isl [A|LA] - X :- memberd(A,X),!,Z isl LA -X.
[A|Z] isl [A|LA] - X :- Z isl LA - X.
%p147
[] isl [] / A.
X isl [A|X] / A :- !.
[C|X] isl [C|CL] / A :- X isl LC / A.
位相空間
上記の述語たちを使って有限個の集合の位相空間を求めます。
top_condition(O0,O) :-
for_any(memberr([U,V],O0,2),
topology_c(U,V,O)).
ptop(Set0) :-
sort(Set0,Set),
ctr_set(0,1),
power0(Power,Set),
O0 isl subset(Power),
O isl [[]|O0] + [Set],
top_condition(O0,O),
write_count(O),
fail.
%p194
writeln(P) :-
write(P),nl.
write_count(O) :-
ctr_inc(0,N),
writeln(N = O).
for_any(P,Q) :-
P,
ifthenelse(Q,fail,(!,fail)).
for_any(P,Q).
計算
ctr_* という述語はカウンターです。ARITY/PROLOG独自のものです。3元の集合の場合、同型を含めると64個あるとされています。同型を除くと数学的には29個です。さあ、出力はどうなるでしょうか。
N-Prolog Ver 4.38
?- ['./tests/iitaka.pl'].
yes
?- ptop([1,2,3]).
1=[[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
2=[[],[1],[2],[3],[1,2],[1,3],[1,2,3]]
3=[[],[1],[2],[3],[1,2],[2,3],[1,2,3]]
4=[[],[1],[2],[3],[1,2],[1,2,3]]
・・・
61=[[],[1,3],[2,3],[1,2,3]]
62=[[],[1,3],[1,2,3]]
63=[[],[2,3],[1,2,3]]
64=[[],[1,2,3]]
no
?-
うまく計算されているようです。ところで4元だと16384個(同型を含む)とされています。1980年代のPC9801とインタプリタのRUN/PROLOGでおよそ2時間の計算時間を要したそうです。現在のマシンとN-Prologではインタプリタでもずっと高速です。
インタプリタでも3秒程度です。技術は進歩したものです。
研究課題
同型なものを判定して3元で29個が求まれば数学的にも正しい答えとなります。同型判定もいずれ取り組みたいと思っています。数学は楽しいです。Prologの数学との親和性を改めて感じています。さあ、次は群論に取り組みましょう。