我目前正在尝试弄清楚如何在 swi-prolog 中跨模块使用相同的运算符及其相关谓词。
我有一个“主”文件(ch20.pl),我通过键入以下内容从 swi-prolog 交互式加载:
[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.
但我真的想将我的逻辑分成更多模块,而不是将所有内容都放在一个文件中。而且我希望能够使用模块应该提供的这个类似公共/私有的系统。
有什么我可以在代码中重新排列的东西,或者我可以用这个多文件谓词以某种方式解决我的问题吗?
顺便说一句,是否有任何书籍教授诸如使用模块和其他高级 prolog 技术之类的内容?因为我发现很难使用 swi-prolog 文档,而且很难用 google 找到示例。