我有一个知识库,包含学生数据库,在'students.pl'文件中,如下所示:
% student(Name,Percent,List_of_Marks_in_3_subjects).
student('abc',83,[80,80,90]).
student('pqr',70,[70,60,80]).
student('xyz',76,[80,70,80]).
我想从知识库访问每个学生谓词,并计算每个主题的平均分数或平均百分比,而不使用'findall'或断言/撤回。 我可能想要像这样使用回溯:
find_score_all(X) :- student(Name,Percent,L),
write(Percent),nl,
fail.
find_score_all(_).
通过这种方法,我可以访问每个元素并编写它,但是如果我想将每个'Percent'值作为元素添加到列表中,或者只使用像'Percent1 is Total + Percent'这样的谓词来计算百分比值然后找到它的平均值,我该怎么办呢? 请注意,我不想使用findall或retract / assert,并且最好通过知识库一次性找到平均值,因为知识库非常大。
感谢任何帮助。
答案 0 :(得分:0)
%solution for sum of percents, you can replace with any other calculation sum_percent predicate.
listing(student/3, convert_to_list/2, sum_percent, sum_percent/2).
% student(Name,Percent,List_of_Marks_in_3_subjects).
student('abc',83,[80,80,90]).
student('pqr',70,[70,60,80]).
student('xyz',76,[80,70,80]).
convert_to_list(X, R):-
student(N, P, LM),
not(member(st(N, P, LM), X)),
convert_to_list([st(N, P, LM)|X], R).
convert_to_list(X, X).
sum_percent:-
convert_to_list([], X),
sum_percent(X, S),
write(S).
sum_percent([], 0).
sum_percent([st(_,E,_)|T], S):-
sum_percent(T, S2),
S is E+S2.
答案 1 :(得分:-1)
如果要添加到列表中,则应使用findall或更好的库(aggregate)。但如果你担心效率,你可以使用类似的东西
integrate(ave, Goal, Ave) :-
State = state(0, 0, _),
repeat,
( call(Goal, V),
arg(1, State, C), U is C+1, nb_setarg(1, State, U),
arg(2, State, S), T is S+V, nb_setarg(2, State, T),
fail
; arg(1, State, C), arg(2, State, S), Ave is S/C
).
:- meta_predicate integrate(+, :, ?).
试验:
members(X) :- member(X, [1,2,3,4]).
?- integrate(ave, members, R).
R = 2.5 .
当然,您需要添加错误处理(至少在计数器C == 0
时)。