2

現在、swi-prolog のモジュール間で同じ演算子とそれに関連する述語を使用する方法を理解しようとしています。

次のように入力してswi-prologインタラクティブからロードする「メイン」ファイル(ch20.pl)があります。

[ch20].

ch20.plには現在以下が含まれています。

:- use_module(ch20_examples).
:- use_module(ch20_Ires).

ch20_examples.pl:

:- module(ch20_examples, [example/2, attribute/2]).

attribute(size, [small, large]).
attribute(shape, [long, compact, other]).
attribute(holes, [none, 1, 2, 3, many]).

example(nut, [size=small, shape=compact, holes=1]).
example(screw, [size=small, shape=long, holes=none]).
example(key, [size=small, shape=long, holes=1]).
example(nut, [size=small, shape=compact, holes=1]).
example(key, [size=large, shape=long, holes=1]).
example(screw, [size=small, shape=compact, holes=none]).
example(nut, [size=small, shape=compact, holes=1]).
example(pen, [size=large, shape=long, holes=none]).
example(scissors, [size=large, shape=long, holes=2]).
example(pen, [size=large, shape=long, holes=none]).
example(scissors, [size=large, shape=other, holes=2]).
example(key, [size=small, shape=other, holes=2]).

ch20_Ires.pl:

:- module(ch20_Ires,
            [   op(900, xfy, <-),
                (<-)/2
            ]).
:- use_module(ch20_utils).

R <- residual_info(Attribute) :-
    findall(X, (example(_, Attributes), member(Attribute=X, Attributes)), Values),
    list_to_set(Values, Values_set),
    setof(Class, Class^Attr^example(Class,Attr), Classes_set),
    Values_prob_sum <- sum_list(Values_set, value_prob(Values, Classes_set, Attribute)),
    R <- -Values_prob_sum, !.

R <- value_prob(Values, Classes_set, Attr, Val) :-
    include(==(Val), Values, Value_count_list),
    Value_count_n <- len(Value_count_list),
    Values_n <- len(Values),
    Val_prob <- Value_count_n / Values_n, 
    R <- Val_prob * sum_list(Classes_set, cond_prob(Attr, Val)), !.

R <- cond_prob(Attr, Val, Class) :-
    findall(_, (example(Class, Class_FeatureList), member(Attr=Val, Class_FeatureList)) , Class_list),
    Class_n <- len(Class_list),
    findall(_, (example(_, FeatureList), member(Attr=Val, FeatureList)), Feature_count_list),
    Feature_count <- len(Feature_count_list),
    (Class_n > 0, Cond_prob <- Class_n / Feature_count, R <- Cond_prob * log2(Cond_prob)
    ;
    R <- 0), !.

ch20_utils.pl:

:- module(ch20_utils,
            [   op(900, xfy, <-),
                (<-)/2
            ]).

R <- log2(X) :- R <- log(X) / log(2), !.
R <- len(L) :- length(L, R), !.
Sum <- sum_list([], _) :- Sum <- 0.
Sum <- sum_list([H|T], Func) :- 
    New_sum <- sum_list(T, Func), 
    !, Func =..Func_list, 
    append(Func_list,[H],Apply_func_list),
    Apply_func =..Apply_func_list,
    Sum <- New_sum + Apply_func.

R <- X :- compound(X), X =..[OP,X2,X3], R2 <- X2, R3 <- X3, Expr =..[OP,R2,R3], R is Expr, !.
R <- X :- R is X, !.

私の現在の目標は、以下を評価できるようにすることです。

?- X <- residual_info(size).

しかし、上記の設定では false を返すだけです...

コードをもう少し読みやすくし、次のような化合物を評価できるようにするために <- 演算子を使用していることに注意してください。

X <- 18*log2(19)-5.

しかし、これは私のコードがその部分に大きく依存していることも意味します:

R <- X :- compound(X), X =..[OP,X2,X3], R2 <- X2, R3 <- X3, Expr =..[OP,R2,R3], R is Expr, !.
R <- X :- R is X, !.

マルチファイル述語をいじってみましたが、使い方がよくわからないと思います。

ただし、ch20_Ires.pl ファイルが次のように変更された場合:

:- module(ch20_Ires,
            [   op(900, xfy, <-),
                (<-)/2
            ]).
 R <- log2(X) :- R <- log(X) / log(2), !.
 R <- len(L) :- length(L, R), !.
 Sum <- sum_list([], _) :- Sum <- 0.
 Sum <- sum_list([H|T], Func) :- 
     New_sum <- sum_list(T, Func), 
     !, Func =..Func_list, 
     append(Func_list,[H],Apply_func_list), 
     Apply_func =..Apply_func_list, 
     Sum <- New_sum + Apply_func.

R <- residual_info(Attribute) :-
    findall(X, (example(_, Attributes), member(Attribute=X, Attributes)), Values),
    list_to_set(Values, Values_set),
    setof(Class, Class^Attr^example(Class,Attr), Classes_set),
    Values_prob_sum <- sum_list(Values_set, value_prob(Values, Classes_set, Attribute)),
    R <- -Values_prob_sum, !.

R <- value_prob(Values, Classes_set, Attr, Val) :-
    include(==(Val), Values, Value_count_list),
    Value_count_n <- len(Value_count_list),
    Values_n <- len(Values),
    Val_prob <- Value_count_n / Values_n,
    R <- Val_prob * sum_list(Classes_set, cond_prob(Attr, Val)), !.

R <- cond_prob(Attr, Val, Class) :-
    findall(_, (example(Class, Class_FeatureList), member(Attr=Val, Class_FeatureList)) , Class_list),
    Class_n <- len(Class_list),
    findall(_, (example(_, FeatureList), member(Attr=Val, FeatureList)), Feature_count_list),
    Feature_count <- len(Feature_count_list),
    (Class_n > 0, Cond_prob <- Class_n / Feature_count, R <- Cond_prob * log2(Cond_prob)
    ;
    R <- 0), !.

R <- X :- compound(X), X =..[OP,X2,X3], R2 <- X2, R3 <- X3, Expr =..[OP,R2,R3], R is Expr, !.
R <- X :- R is X, !.

すべてが正常に機能し、目標を実行できます。

?- X <- residual_info(size).
X = 1.5421864522230475.

しかし、すべてを 1 つのファイルにまとめるのではなく、ロジックをより多くのモジュールに分割したいと考えています。そして、モジュールが提供することになっているこのパブリック/プライベートのようなシステムを使用できるようにしたいと考えています。

コードで再配置できるものはありますか、またはこのマルチファイル述語で問題を解決できますか?

余談ですが、モジュールやその他の高度なプロローグ手法の使用などを教えている本はありますか? swi-prolog のドキュメントを使用するのは非常に難しく、Google で例を見つけるのは難しいためです。

4

1 に答える 1