125 lines
3.5 KiB
Prolog
125 lines
3.5 KiB
Prolog
|
|
%parfactor(
|
|
% [ability(P),grade(C,S), satisfaction(C,S,P)],
|
|
% \phi = [....],
|
|
% [P,C,S],
|
|
% [P \in [p1,p2,p4], C \in [c1,c3], S \in [s2,s3]]).
|
|
% [S \= s2])
|
|
|
|
|
|
:- module(clpbn_ground_factors, [
|
|
generate_network/5]).
|
|
|
|
:- use_module(library(bhash), [
|
|
b_hash_new/1,
|
|
b_hash_lookup/3,
|
|
b_hash_insert/4]).
|
|
|
|
:- use_module(library(lists), [
|
|
delete/3,
|
|
nth0/3,
|
|
member/2]).
|
|
|
|
:- use_module(library(pfl), [
|
|
factor/6,
|
|
defined_in_factor/2,
|
|
skolem/2]).
|
|
|
|
:- use_module(library(clpbn/dists), [
|
|
dist/4]).
|
|
|
|
:- dynamic currently_defined/1, f/4.
|
|
|
|
generate_network(QueryVars0, QueryKeys, Keys, Factors, Evidence) :-
|
|
attributes:all_attvars(AVars),
|
|
keys(QueryVars0, QueryKeys0),
|
|
check_for_evidence(AVars, EVars, QueryKeys0, QueryVars0, Evidence),
|
|
check_for_extra_bindings(QueryVars0, QueryVars, QueryKeys0, QueryKeys),
|
|
do_network(QueryVars, EVars, Keys, Factors).
|
|
|
|
do_network([], _, _, _) :- !.
|
|
do_network(QueryVars, EVars, Keys, Factors) :-
|
|
retractall(currently_defined(_)),
|
|
retractall(f(_,_,_,_)),
|
|
run_through_factors(QueryVars),
|
|
run_through_factors(EVars),
|
|
findall(K, currently_defined(K), Keys),
|
|
findall(f(FType,FId,FKeys,FCPT), f(FType,FId,FKeys,FCPT), Factors).
|
|
|
|
%
|
|
% look for attributed vars with evidence (should also search the DB)
|
|
% verifiy if the evidence overlaps with query
|
|
% bind query if so.
|
|
%
|
|
check_for_evidence(V.AVars, V.EVars, QueryKeys, QueryVars, (K=E).Evidence) :-
|
|
clpbn:get_atts(V,[key(K),evidence(E)]), !,
|
|
check_for_evidence_in_query(K, QueryKeys, QueryVars, E),
|
|
check_for_evidence(AVars, EVars, QueryKeys, QueryVars, Evidence).
|
|
% ignore no evidence vars
|
|
check_for_evidence(_V.AVars, EVars, QueryKeys, QueryVars, Evidence) :-
|
|
check_for_evidence(AVars, EVars, QueryKeys, QueryVars, Evidence).
|
|
check_for_evidence([], [], _, _, []).
|
|
|
|
%
|
|
% do we still have free query variables?
|
|
%
|
|
check_for_extra_bindings([], [], [], []).
|
|
check_for_extra_bindings([V|QueryVars0], QueryVars, [_|QueryKeys0], QueryKeys) :-
|
|
nonvar(V),!,
|
|
check_for_extra_bindings(QueryVars0, QueryVars, QueryKeys0, QueryKeys).
|
|
check_for_extra_bindings([V|QueryVars0], [V|QueryVars], [K|QueryKeys0], [K|QueryKeys]) :-
|
|
check_for_extra_bindings(QueryVars0, QueryVars, QueryKeys0, QueryKeys).
|
|
|
|
|
|
check_for_evidence_in_query(Key, [Key|QueryKeys], [V|QueryVars], E) :- !,
|
|
skolem(Key, Dom),
|
|
nth0(E, Dom, Val),
|
|
V = Val,
|
|
check_for_evidence_in_query(Key, QueryKeys, QueryVars, E).
|
|
check_for_evidence_in_query(Key, [_|QueryKeys], [_|QueryVars], E) :-
|
|
check_for_evidence_in_query(Key, QueryKeys, QueryVars, E).
|
|
check_for_evidence_in_query(_Key, [], [], _E).
|
|
|
|
keys([], []).
|
|
keys([Var|QueryVars], [Key|QueryKeys]) :-
|
|
clpbn:get_atts(Var,[key(Key)]),
|
|
keys(QueryVars, QueryKeys).
|
|
|
|
run_through_factors([]).
|
|
run_through_factors([Var|_QueryVars]) :-
|
|
clpbn:get_atts(Var,[key(K)]),
|
|
find_factors(K),
|
|
fail.
|
|
run_through_factors([_|QueryVars]) :-
|
|
run_through_factors(QueryVars).
|
|
|
|
initialize_evidence([]).
|
|
initialize_evidence([V|EVars]) :-
|
|
clpbn:get_atts(V, [key(K)]),
|
|
assert(currently_defined(K)),
|
|
initialize_evidence(EVars).
|
|
|
|
%
|
|
% gets key K, and collects factors that define it
|
|
find_factors(K) :-
|
|
\+ currently_defined(K),
|
|
assert(currently_defined(K)),
|
|
defined_in_factor(K, ParFactor),
|
|
add_factor(ParFactor, Ks),
|
|
member(K1, Ks),
|
|
\+ currently_defined(K1),
|
|
find_factors(K1).
|
|
|
|
add_factor(factor(Type, Id, Ks, _, Phi, Constraints), Ks) :-
|
|
F = f(Type, Id, Ks, CPT),
|
|
( is_list(Phi) -> CPT = Phi ; call(user:Phi, CPT) ),
|
|
run(Constraints),
|
|
\+ f(Type, Id, Ks, CPT),
|
|
assert(F).
|
|
|
|
run([Goal|Goals]) :-
|
|
call(user:Goal),
|
|
run(Goals).
|
|
run([]).
|
|
|