fove initial skeleton.w

This commit is contained in:
Vítor Santos Costa
2012-01-10 17:01:06 +00:00
parent aef7555e02
commit a25c97c295
14 changed files with 625 additions and 201 deletions

View File

@@ -7,7 +7,6 @@
:- module(clpbn_bp,
[bp/3,
check_if_bp_done/1,
set_solver_parameter/2,
use_log_space/0,
init_bp_solver/4,
@@ -72,7 +71,7 @@ bp([QueryVars], AllVars, Output) :-
clpbn_bind_vals([QueryVars], LPs, Output).
init_bp_solver(_, AllVars0, _, bp(BayesNet, DistIds, AllParFactors)) :-
init_bp_solver(_, AllVars0, _, bp(BayesNet, DistIds, _AllParFactors)) :-
check_for_agg_vars(AllVars0, AllVars),
%inc_network_counting,
%writeln_clpbn_vars(AllVars),
@@ -100,126 +99,6 @@ parents_to_keys(Var.Parents, Key.Keys) :-
clpbn:get_atts(Var, [key(Key)]),
parents_to_keys(Parents, Keys).
generate_parfactors(AllVars, ParFactors) :-
generate_factors(AllVars, Factors),
%writeln(Factors),
% sort factors by distribution
% sort(Factors, DistFactors),
%writeln(DistFactors),
group(DistFactors, ParFactors).
%writeln(ParFactors).
generate_factors(Var.AllVars, f(Dist,[Var|Parents]).AllFactors) :-
clpbn:get_atts(Var, [dist(Dist,Parents)]),
generate_factors(AllVars, AllFactors).
generate_factors([], []).
group([], []).
group(f(Dist,Vs).DistFactors, phi(Dist,NConstraints,Domain).ParFactors) :-
number(Dist),
grab_similar_factors(Dist, Vs, f(Dist,Vs).DistFactors, RemainingDistFactors, Constraints),
simplify_constraints(Constraints, NConstraints, Domain), !,
group(RemainingDistFactors, ParFactors).
group(f(Dist,Vs).DistFactors, phi(Dist,Constraints,[]).ParFactors) :-
grab_similar_factors(Dist, Vs, f(Dist,Vs).DistFactors, RemainingDistFactors, Constraints),
group(RemainingDistFactors, ParFactors).
simplify_constraints([[1=El]|Constraints], [NEl], [in(1,NEl,Domain)]) :-
functor(El,Name,1), !,
functor(NEl,Name,1),
constraints_to_domain(1,[[1=El]|Constraints],Domain0),
sort(Domain0, Domain).
simplify_constraints(Constraints, NewConstraints, Ds) :-
Constraints = [Constraint|_],
generate_domains(Constraint, Constraints, Ds), !,
normalize_constraints(Ds, Constraints, NewConstraints).
simplify_constraints(Constraints, Constraints, []).
normalize_constraints(Ds, Constraints, [T|GeneralizedConstraints]) :-
unique(Ds, I, T, RemDs), !,
remove_i(Constraints, I, ConstraintsI),
normalize_constraints(RemDs, ConstraintsI, GeneralizedConstraints).
normalize_constraints(Ds, Constraints, [(S1,S2)|GeneralizedConstraints]) :-
equal(Ds, I, J, RemDs, S1, S2),
arg(1,S1,V),
arg(1,S2,V),
%writeln(start:Ds:I:J),
remove_eqs(Constraints, I, J, ConstraintsI), !,
normalize_constraints(RemDs, ConstraintsI, GeneralizedConstraints).
normalize_constraints(_Ds, Constraints, []) :-
Constraints = [[_]|_], !.
normalize_constraints(_, Constraints, Constraints).
unique([in(I,T,[_])|Ds], I, T, Ds).
unique([D|Ds], I, T, D.NewDs) :-
unique(Ds, I, T, NewDs).
equal([in(I,S1,Vals)|Ds], I, J, Ds, S1, S2) :-
equal2(Ds, Vals, J, S2), !.
equal([D|Ds], I, J, D.NewDs, S1, S2) :-
equal(Ds, I, J, NewDs, S1, S2).
equal2([in(J,S2,Vals)|Ds], Vals, J, S2).
equal2([D|Ds], Vals, J, S2) :-
equal2(Ds, Vals, J, S2).
remove_i([], _I, []).
remove_i(C.Constraints, I, NewC.ConstraintsI) :-
remove_ic(C,I,NewC),
remove_i(Constraints, I, ConstraintsI).
remove_ic([I=_|C], I, C) :- !.
remove_ic(El.C, I, El.NewC) :-
remove_ic(C, I, NewC).
remove_eqs([], _I, _J, []).
remove_eqs(C.Constraints, I, J, NewC.ConstraintsI) :-
remove_eqs2(C, I, J, NewC),
remove_eqs(Constraints, I, J, ConstraintsI).
remove_eqs2([I=V|C], I, J, C) :- !,
arg(1,V,A),
check_match(C, J, A).
remove_eqs2(El.C, I, J, El.NewC) :-
remove_eqs2(C, I, J, NewC).
check_match([J=V1|C], J, V) :- !,
arg(1,V1,V).
check_match(El.C, J, V) :-
check_match(C, J, V).
generate_domains([], _Constraints, []).
generate_domains([I=El|Constraint], Constraints, in(I,NEl,Domain).Ds) :-
functor(El,Name,1), !,
functor(NEl,Name,1),
constraints_to_domain(I,Constraints,Domain0),
sort(Domain0, Domain),
generate_domains(Constraint, Constraints, Ds).
constraints_to_domain(_,[],[]).
constraints_to_domain(I,[Constraint|Constraints],El.Domain) :-
add_constraint_to_domain(I, Constraint, El),
constraints_to_domain(I,Constraints,Domain).
add_constraint_to_domain(I, [I=El|_], A) :- !,
arg(1, El, A).
add_constraint_to_domain(I, _.Constraint, El) :-
add_constraint_to_domain(I, Constraint, El).
grab_similar_factors(Dist, Vs, f(Dist,DVs).DistFactors, RemainingDistFactors, Constraint.Constraints) :-
grab_similar_factor(DVs, 1, Constraint), !,
grab_similar_factors(Dist, Vs, DistFactors, RemainingDistFactors, Constraints).
grab_similar_factors(_Dist, _Vs, DistFactors, DistFactors, []).
grab_similar_factor([], _Arg, []).
grab_similar_factor(V.VDVs, Arg, (Arg=Key).Constraint) :-
clpbn:get_atts(V,key(Key)),
Arg1 is Arg+1,
grab_similar_factor(VDVs, Arg1, Constraint).
process_ids([], _, []).

View File

@@ -179,6 +179,10 @@ add_dist(Domain, Type, CPT, Parents, Key, Id) :-
record_parent_sizes([], Id, [], DSizes) :-
recordz(clpbn_dist_psizes,db(Id, DSizes),_).
record_parent_sizes([P|Parents], Id, [Size|Sizes], DSizes) :-
integer(P), !,
Size = P,
record_parent_sizes(Parents, Id, Sizes, DSizes).
record_parent_sizes([P|Parents], Id, [Size|Sizes], DSizes) :-
clpbn:get_atts(P,dist(Dist,_)), !,
get_dist_domain_size(Dist, Size),

View File

@@ -8,7 +8,7 @@
store_evidence/1,
incorporate_evidence/2,
check_stored_evidence/2,
add_evidence/2,
add_stored_evidence/2,
put_evidence/2
]).
@@ -19,7 +19,7 @@
]).
:- use_module(library('clpbn/dists'), [
get_evidence_position/3
get_dist/4
]).
:- use_module(library(rbtrees), [
@@ -30,7 +30,7 @@
:- meta_predicate store_evidence(:).
:- dynamic node/4, edge/2, evidence/2.
:- dynamic node/3, edge/2, evidence/2.
%
% new evidence storage algorithm. The idea is that instead of
@@ -46,28 +46,42 @@ store_evidence(G) :-
compute_evidence(G, PreviousSolver).
compute_evidence(G, PreviousSolver) :-
catch(call_residue(G, Vars), Ball, evidence_error(Ball,PreviousSolver)), !,
store_graph(Vars),
catch(get_clpbn_vars(G, Vars), Ball, evidence_error(Ball,PreviousSolver)), !,
store_graph(Vars), !,
set_clpbn_flag(solver, PreviousSolver).
compute_evidence(_,PreviousSolver) :-
set_clpbn_flag(solver, PreviousSolver).
get_clpbn_vars(G, Vars) :-
% attributes:all_attvars(Vars0),
once(G),
attributes:all_attvars(Vars).
evidence_error(Ball,PreviousSolver) :-
set_clpbn_flag(solver,PreviousSolver),
throw(Ball).
store_graph([]).
store_graph([_-node(K,Dom,CPT,TVs,Ev)|Vars]) :-
\+ node(K,_,_,_), !,
assert(node(K,Dom,CPT,TVs)),
( nonvar(Ev) -> assert(evidence(K,Ev)) ; true),
store_graph([V|Vars]) :-
clpbn:get_atts(V,[key(K),dist(Id,Vs)]),
\+ node(K, Id, _), !,
translate_vars(Vs,TVs),
assert(node(K,Id,TVs)),
( clpbn:get_atts(V,[evidence(Ev)]) -> assert(evidence(K,Ev)) ; true),
add_links(TVs,K),
store_graph(Vars).
store_graph([_|Vars]) :-
store_graph(Vars).
translate_vars([],[]).
translate_vars([V|Vs],[K|Ks]) :-
clpbn:get_atts(V, [key(K)]),
translate_vars(Vs,Ks).
add_links([],_).
add_links([K0|TVs],K) :-
edge(K,K0), !,
add_links(TVs,K).
add_links([K0|TVs],K) :-
assert(edge(K,K0)),
add_links(TVs,K).
@@ -82,7 +96,7 @@ incorporate_evidence(Vs,AllVs) :-
create_open_list([], L, L, C, C).
create_open_list([V|Vs], [K-V|OL], FL, C0, CF) :-
clpbn:get_atts(V,[key(K)]),
add_evidence(K, V),
add_stored_evidence(K, V),
rb_insert(C0, K, V, CI),
create_open_list(Vs, OL, FL, CI, CF).
@@ -91,12 +105,26 @@ do_variables([K-V|Vs], Vf, C0) :-
check_for_evidence(K, V, Vf, Vff, C0, Ci),
do_variables(Vs, Vff, Ci).
create_new_variable(K, V, Vf0, Vff, C0, Cf) :-
node(K,Dom, CPT, TVs),
{ V = K with p(Dom, CPT, NTVs) },
add_evidence(K, V),
add_variables(TVs, NTVs, Vf0, Vff, C0, Cf).
extract_vars([], []).
extract_vars([_-V|Cache], [V|AllVs]) :-
extract_vars(Cache, AllVs).
%make sure that we are consistent
check_stored_evidence(K, Ev) :-
evidence(K, Ev0), !,
Ev0 = Ev.
check_stored_evidence(_, _).
add_stored_evidence(K, V) :-
evidence(K, Ev), !,
put_evidence(Ev, V).
add_stored_evidence(_, _).
check_for_evidence(_, V, Vf, Vf, C, C) :-
clpbn:get_atts(V, [evidence(_)]), !.
check_for_evidence(K, _, Vf0, Vff, C0, Ci) :-
findall(Rt,edge(Rt,K),Rts),
add_variables(Rts, _, Vf0, Vff, C0, Ci).
add_variables([], [], Vf, Vf, C, C).
add_variables([K|TVs], [V|NTVs], Vf0, Vff, C0, Cf) :-
@@ -107,30 +135,22 @@ add_variables([K|TVs], [V|NTVs], [K-V|Vf0], Vff, C0, Cf) :-
create_new_variable(K, V, Vf0, Vf1, C1, C2),
add_variables(TVs, NTVs, Vf1, Vff, C2, Cf).
create_new_variable(K, V, Vf0, Vff, C0, Cf) :-
node(K, Id, TVs),
writeln(add:K:Id),
get_dist(Id,_,Dom,CPT), !,
{ V = K with p(Dom, CPT, NTVs) },
add_stored_evidence(K, V),
add_variables(TVs, NTVs, Vf0, Vff, C0, Cf).
create_new_variable(K, V, Vf0, Vff, C0, Cf) :-
node(K, Id, TVs),
Id =.. [Na,Dom],
Dist =.. [Na,Dom,NTVs],
{ V = K with Dist },
writeln(done),
add_stored_evidence(K, V),
add_variables(TVs, NTVs, Vf0, Vff, C0, Cf).
extract_vars([], []).
extract_vars([_-V|Cache], [V|AllVs]) :-
extract_vars(Cache, AllVs).
%make sure that we are
check_stored_evidence(K, Ev) :-
evidence(K, Ev0), !, Ev0 = Ev.
check_stored_evidence(_, _).
add_evidence(K, V) :-
evidence(K, Ev), !,
store_evidence(V, Ev),
clpbn:put_atts(V, [evidence(Ev)]).
add_evidence(_, _).
check_for_evidence(_, V, Vf, Vf, C, C) :-
clpbn:get_atts(V, [evidence(_)]), !.
check_for_evidence(K, _, Vf0, Vff, C0, Ci) :-
findall(Rt,edge(Rt,K),Rts),
add_variables(Rts, _, Vf0, Vff, C0, Ci).
put_evidence(K, V) :-
clpbn:get_atts(V, [dist(Id,_)]),
get_evidence_position(K, Id, Ev),
put_evidence(Ev, V) :-
clpbn:put_atts(V, [evidence(Ev)]).

View File

@@ -0,0 +1,94 @@
:- module(clpbn_fove,
[fove/3,
set_solver_parameter/2,
init_fove_solver/4,
run_fove_solver/3,
finalize_fove_solver/1
]).
:- use_module(library(pfl), [
factor/5,
skolem/2]).
%
% support fove method
%
fove([[]],_,_) :- !.
fove([QueryVars], AllVars, Output) :-
init_fove_solver(_, AllVars, _, GraphicalNet),
run_fove_solver([QueryVars], LPs, GraphicalNet),
finalize_fove_solver(GraphicalNet),
clpbn_bind_vals([QueryVars], LPs, Output).
%
% set up network, add evidence, and query all marginals at the same time?
%
init_fove_solver(_, AllAttVars, _, fove(ParNet, EvidenceVariables)) :-
all_factors(Factors),
all_domains(Domains),
evidence_variables(AllAttVars, EvidenceVariables),
writeln(ev:EvidenceVariables),
% c-code, just receives the par factors
init_fove(Factors, Domains, ParNet).
evidence_variables([], []).
evidence_variables(V.AllAttVars, [K:E|EvidenceVariables]) :-
clpbn:get_atts(V,[key(K),evidence(E)]), !,
evidence_variables(AllAttVars, EvidenceVariables).
evidence_variables(_V.AllAttVars, EvidenceVariables) :-
evidence_variables(AllAttVars, EvidenceVariables).
all_domains(Domains) :-
findall(X:Y, skolem(X,Y), Domains).
:- table all_factors/1.
%
% enumerate all par-factors and enumerate their domain as tuples.
%
% output is list of pf(
% ID: an unique number
% Ks: a list of keys, also known as the pf formula [a(X),b(Y),c(X,Y)]
% Vs: the list of free variables [X,Y]
% Phi: the table following usual CLP(BN) convention
% Tuples: tuples with all ground bindings for variables in Vs, of the form [fv(x,y)]
%
all_factors(Factors) :-
findall(F, is_factor(F), Factors).
is_factor(pf(Id, Ks, Vs, Phi, Tuples)) :-
factor(Id, Ks, Vs, Table, Constraints),
Table \= avg,
gen_table(Table, Phi),
all_tuples(Constraints, Vs, Tuples).
gen_table(Table, Phi) :-
( is_list(Table)
->
Phi = Table
;
call(user:Table, Phi)
).
all_tuples(Constraints, Tuple, Tuples) :-
setof(Tuple, Constraints^run(Constraints), Tuples).
run([]).
run(Goal.Constraints) :-
user:Goal,
run(Constraints).
%
% ask probability of a single variable
%
run_fove_solver(QueryVars, LPs, fove(ParFactors, EvidenceVariables)) :-
fove(QueryVars, EvidenceVariables, ParFactors, LPs).

View File

@@ -0,0 +1,232 @@
%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_bn/2,
ground_parfactors/1]).
:- use_module(library(bhash), [
b_hash_new/1,
b_hash_lookup/3,
b_hash_insert/4]).
:- use_module(library(pfl), [
factor/5,
skolem/2]).
:- use_module(library(clpbn/dists), [
dist/4]).
%
% generate a CLP(BN) network that can be run in CLP(BN).
%
generate_bn(QueryVars, AllAttVars) :-
attributes:all_attvars(AVars),
b_hash_new(H0),
check_for_evidence(AVars, EVars),
run_through_factors(QueryVars, H0, H1, AllAttVars, IVars),
run_through_factors(EVars, H1, _HF, IVars, []).
check_for_evidence(V.AVars, V.EVars) :-
clpbn:get_atts(V,[evidence(_E)]), !,
check_for_evidence(AVars, EVars).
check_for_evidence(_V.AVars, EVars) :-
check_for_evidence(AVars, EVars).
check_for_evidence([], []).
run_through_factors([], H, H) --> [].
run_through_factors(V.Vars, H0, HF) -->
{ clpbn:get_atts(V,[key(K)]),
b_hash_lookup(K,V,H0)
}, !,
run_through_factors(Vars, H0, HF).
run_through_factors(V.Vars, H0, HF) -->
% it is a new clpbn variable
[V],
{
% should already have a key
clpbn:get_atts(V,[key(K)]),
% insert it into a table of seen variables
b_hash_insert(H0,K,V,HI),
construct_clpbn_node(K, V, HI, MoreVars, Vars)
},
run_through_factors(MoreVars, HI, HF).
% aggregates are special.
construct_clpbn_node(K, V, HI) -->
% and get the corresponding factor
{ factor(Id, [K|Ks], _, avg, Constraints) }, !,
{
skolem(K, Domain),
dist(avg(Domain, Parents), DistId, K, Parents),
clpbn:put_atts(V,[dist(DistId,Parents)]),
% we also need to set the constraints
% this should set all the keys to rights
run(Constraints)
},
% now let's look up parents and set up the graph
run_bayesian_factor(Ks, HI, Parents, []).
construct_clpbn_node(K, V, HI) -->
{
% and get the corresponding factor
factor(Id, [K|Ks], _, _Phi, Constraints),
factor_to_dist(Id, DistId),
% and the dist constraint
clpbn:put_atts(V,[dist(DistId,Parents)]),
% we also need to set the constraints
% this should set all the keys to rights
run(Constraints)
},
% now let's look up parents and set up the graph
run_bayesian_factor(Ks, HI, Parents, []).
factor_to_dist(Id, NewId) :-
factor(Id, [K|Ks], _, Phi, _Constraints),
skolem(K, Domain),
( is_list(Phi)
->
CPT = Phi
;
call(user:Phi, CPT)
),
keys_to_sizes(Ks, Szs),
dist(p(Domain, CPT, Szs), NewId, K, Szs).
keys_to_sizes([], []).
keys_to_sizes(K.Ks, Sz.Szs) :-
skolem(K, Domain),
length(Domain, Sz),
keys_to_sizes(Ks, Szs).
run([]).
run(Goal.Constraints) :-
user:Goal, !,
run(Constraints).
run_bayesian_factor([], _H, Vs, Vs) --> [].
run_bayesian_factor(K.Ks, H, Vs, Vs0) -->
run_var(K, H, Vs, Vs1),
run_bayesian_factor(Ks, H, Vs1, Vs0).
%
% this function returns a list of *new* variables
%
% collection of random variables
run_var(avg(Els), H, Vs, Vs0) --> !,
run_vars(Els, H, Vs, Vs0).
% existing random variable
run_var(K, H, V.Vs, Vs) -->
{ b_hash_lookup(K,V,H) }, !.
% new random variable
run_var(K, _H, V.Vs, Vs) -->
[V],
{
clpbn:put_atts(V,[key(K)])
}.
run_vars([], _H, Vs, Vs) --> [].
run_vars(K.Els, H, Vs, Vs0) -->
run_var(K, H, Vs, VsI),
run_vars(Els, H, VsI, Vs0).
ground_parfactors(ParFactors) :-
findall(Factor, factor(Factor), SourceFactors),
run_all_parfactors(SourceFactors, ParFactors).
factor(Factor) :-
user:parfactor(Factor).
factor(Factor) :-
user:bayes(Factor).
run_all_parfactors([], []).
run_all_parfactors(Source.SourceFactors, Factor.ParFactors) :-
run_parfactors(Source, Factor),
run_all_parfactors(SourceFactors, ParFactors).
run_parfactors((Formula ; Phi ; ConstraintGenerator), parfactor(Formula, Phi, FV, Domain, NewConstraints)) :-
term_variables(Formula, FreeVars),
FV =.. fv(FreeVars),
evaluate_constraints(FV, ConstraintGenerator, NewConstraints, Domain).
evaluate_constraints(FreeVars, Constraint.ConstraintGenerators, NC, Domain) :-
functor(FreeVars, fv, NOf),
setof(FreeVars, user:Constraint, Bindings),
run_free_vars(0, NOf, FreeVars, Bindings, Domain, Domain0),
get_list_of_conditions(Domain, 0, N, Conditions),
add_extra_constraints(N, Conditions, Bindings, NC, NC0),
evaluate_constraints(FreeVars, ConstraintGenerators, NC0, Domain0).
evaluate_constraints(_FreeVars, [], []).
run_free_vars(N, N, _FreeVars, _Bindings) --> !.
run_free_vars(I0, N, FreeVars, Bindings) -->
{ I is I0+1,
arg(I, FreeVars, V),
Bindings = B._,
arg(I, B, C), ground(C)
}, !,
{ setof(C, check_val(Bindings, I, C), Dom) },
[domain(I,V,Dom)],
run_free_vars(I, N, FreeVars, Bindings).
run_free_vars(I0, N, FreeVars, Bindings) -->
I is I0+1,
run_free_vars(I, N, FreeVars, Bindings).
add_extra_constraints(0, [], _Bindings) --> !.
add_extra_constraints(1, _Conditions, _Bindings) --> !.
add_extra_constraints(N, Conditions, Bindings) -->
{ extract_unique(Conditions, NewConditions) }, !,
{ N1 is N-1 },
add_extra_constraints(N1, NewConditions, Bindings).
add_extra_constraints(N, [dom(I1,V1,Dom1),dom(I2,V2,Dom2)|Conditions], Bindings) -->
{ length(Dom1, Sz), length(Dom2, Sz) }, !,
{ N1 is N-2 },
{ generate_map(Bindings, I1, I2, Mapping) },
[map(V1,V2,Mapping)],
add_extra_constraints(N1, dom(I1,V1,Dom1).Conditions, Bindings).
add_extra_constraints(_N, Conditions, Bindings) -->
[or(Vs,Or)],
{ gather_vs(Conditions, Vs, Indices),
generate(Bindings, Indices, Or) }.
% domain is a singleton constant
extract_unique(domain(_,_,[_]).Conditions, Conditions) :- !.
extract_unique(_.Conditions, NewConditions) :-
extract_unique(Conditions, NewConditions).
get_list_of_conditions([], N, N, []).
get_list_of_conditions(Dom._, N, N, _Conditions) :-
var(Dom), !.
get_list_of_conditions(Dom.Domain, I0, N, Dom.Conditions) :-
I is I0+1,
get_list_of_conditions(Domain, I, N, Conditions).
check_val(B._Bindings, I, C) :-
arg(I, B, C).
check_val(_.Bindings, I, C) :-
check_val(Bindings, I, C).
generate_map(B.Bindings, I1, I2, [[A1|A2]|Mapping]) :-
arg(I1, B, A1),
arg(I2, B, A2),
generate_map(Bindings, I1, I2, Mapping).
gather_vs([], [], []).
gather_vs(domain(I,V,_).Conditions, V.Vs, I.Indices) :-
gather_vs(Conditions, Vs, Indices).
generate([], _, []).
generate(B.Bindings, Indices, O.Or) :-
generate_el(B, Indices, O),
generate(Bindings, Indices, Or).
generate_el(_B, [], []).
generate_el(B, I.Indices, A.O) :-
arg(I, B, A),
generate_el(B, Indices, O).

View File

@@ -36,6 +36,7 @@
matrix_dims/2,
matrix_sum/2,
matrix_sum_logs_out/3,
matrix_sum_out/3,
matrix_sum_logs_out_several/3,
matrix_op_to_all/4,
matrix_to_exps2/1,
@@ -61,7 +62,9 @@ project_from_CPT(V,tab(Table,Deps,_),tab(NewTable,NDeps,NSzs)) :-
matrix_dims(NewTable, NSzs).
project_from_CPT(V,tab(Table,Deps,_),tab(NewTable,NDeps,NSzs)) :-
vnth(Deps, 0, V, N, NDeps),
% matrix_to_exps2(Table),
matrix_sum_logs_out(Table, N, NewTable),
% matrix_to_logs(NewTable),
matrix_dims(NewTable, NSzs).
evidence(V, Pos) :-