This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/CLPBN/mlns.yap

213 lines
4.8 KiB
Plaintext
Raw Normal View History

2013-06-07 01:18:46 +01:00
:- module(mln,
[op(1150,fx,mln),
op(1150,fx,mln_domain),
mln_domain/1]).
:- use_module(library(pfl)).
:- use_module(library(maplist)).
2013-06-08 00:22:42 +01:00
:- use_module(library(lists)).
2013-06-07 01:18:46 +01:00
:- dynamic mln/1, mln/2, mln_domain/4.
user:term_expansion(mln_domain(P),[]) :-
2013-06-08 00:22:42 +01:00
expand_domain(P).
2013-06-07 01:18:46 +01:00
user:term_expansion( mln(W: D), pfl:factor(markov,Id,FList,FV,Phi,Constraints)) :-
translate_to_factor(W, D, FList, Id, FV, Phi, Constraints),
writeln(factor(markov,Id,FList,FV,Phi,Constraints)).
2013-06-08 00:22:42 +01:00
expand_domain((P1,P2)) :- !,
expand_domain(P1),
expand_domain(P2).
expand_domain(P) :-
P =.. [Name|Types],
functor(P, Name, Arity),
functor(NP, Name, Arity),
foldl(do_type(NP), Types, 1, _).
2013-06-07 01:18:46 +01:00
do_type(NP, Type, I0, I) :-
I is I0+1,
arg(I0, NP, A),
TypeG =.. [Type, A],
assert(mln_domain(I0, NP, TypeG, A)).
translate_to_factor(W, D, Lits, Id, Vs, Phi, Domain) :-
W0 is exp(W),
2013-06-08 00:22:42 +01:00
(
disj_to_list(D, LP, [], Lits, [])
->
findall(F, weight(LP, W0, 1, F), Phi)
;
conj_to_list(D, LP, [], Lits, [])
->
findall(F, weight(LP, 1, W0, F), Phi)
;
cnf(D, Fs0, []),
clean_cnf(Fs0, Fs)
->
member( LP, Fs),
findall(F, weight(LP, W0, 1, F), Phi),
maplist(remove_not, LP, Lits)
),
new_mln(Id),
2013-06-07 01:18:46 +01:00
maplist(new_skolem(Id), Lits),
term_variables(Lits, Vs),
create_domain(Lits, Domain).
2013-06-08 00:22:42 +01:00
2013-06-07 01:18:46 +01:00
new_skolem(Id, Lit) :-
pfl:new_skolem(Lit, [t,f]),
assert(pfl:skolem_in(Lit, Id)).
mln(0).
new_mln(Id) :-
retract(mln(Id)),
Id1 is Id+1,
assert(mln(Id1)).
%
% make it easier to manipulate
%
disj_to_list((C1;C2), L1, L10, L, L0) :-
!,
2013-06-08 00:22:42 +01:00
disj_to_list2(C1, L1, L1I, L, LI),
disj_to_list2(C2, L1I, L10, LI, L0).
disj_to_list((C1+C2), L1, L10, L, L0) :-
!,
disj_to_list2(C1, L1, L1I, L, LI),
disj_to_list2(C2, L1I, L10, LI, L0).
disj_to_list2((C1;C2), L1, L10, L, L0) :-
!,
disj_to_list2(C1, L1, L1I, L, LI),
disj_to_list2(C2, L1I, L10, LI, L0).
disj_to_list2((C1+C2), L1, L10, L, L0) :-
!,
disj_to_list2(C1, L1, L1I, L, LI),
disj_to_list2(C2, L1I, L10, LI, L0).
disj_to_list2((_C1,_C2), _L1, _L10, _L, _L0) :- !, fail.
disj_to_list2((_C1*_C2), _L1, _L10, _L, _L0) :- !, fail.
disj_to_list2((\+ C), [(-C)|L1], L1, [C|L], L) :- literal(C), !.
disj_to_list2((- C), [(-C)|L1], L1, [C|L], L) :- literal(C), !.
disj_to_list2(C, [C|L1], L1, [C|L], L).
conj_to_list((C1,C2), L1, L10, L, L0) :-
!,
conj_to_list2(C1, L1, L1I, L, LI),
conj_to_list2(C2, L1I, L10, LI, L0).
conj_to_list((C1*C2), L1, L10, L, L0) :-
!,
conj_to_list2(C1, L1, L1I, L, LI),
conj_to_list2(C2, L1I, L10, LI, L0).
conj_to_list2((_C1;_C2), _L1, _L10, _L, _L0) :- !, fail.
conj_to_list2((_C1+_C2), _L1, _L10, _L, _L0) :- !, fail.
conj_to_list2((C1,C2), L1, L10, L, L0) :-
!,
conj_to_list2(C1, L1, L1I, L, LI),
conj_to_list2(C2, L1I, L10, LI, L0).
conj_to_list2((C1*C2), L1, L10, L, L0) :-
!,
conj_to_list2(C1, L1, L1I, L, LI),
conj_to_list2(C2, L1I, L10, LI, L0).
conj_to_list2((\+ C), [(C)|L1], L1, [C|L], L) :- literal(C), !.
conj_to_list2((- C), [(C)|L1], L1, [C|L], L) :- literal(C), !.
conj_to_list2(C, [-C|L1], L1, [C|L], L).
remove_not(-G, G) :- !.
remove_not( G, G).
2013-06-07 01:18:46 +01:00
%
% compute the weight table, assuming it is a disjunction
%
2013-06-08 00:22:42 +01:00
weight([(- _)], W0, W1, P) :- !,
2013-06-07 01:18:46 +01:00
% true case false case
2013-06-08 00:22:42 +01:00
( P = W1 ; P = W0 ).
weight([_], W0, W1, P) :- !,
2013-06-07 01:18:46 +01:00
% true case false case
2013-06-08 00:22:42 +01:00
( P = W0 ; P = W1 ).
weight([(- _)|R], W0, W1, P) :- !,
2013-06-07 01:18:46 +01:00
% true case false case
2013-06-08 00:22:42 +01:00
( weight(R, W0, W1, P) ; weight(R, W0, W1, _), P = W0 ).
weight([_|R], W0, W1, P) :-
2013-06-07 01:18:46 +01:00
% true case false case
2013-06-08 00:22:42 +01:00
( weight(R, W0, W1, _), P = W0 ; weight(R, W0, W1, P) ).
2013-06-07 01:18:46 +01:00
create_domain(Lits, Domain) :-
foldl(create_goals, Lits, RDomain, []),
sort(RDomain, Domain).
create_goals(Lit) -->
{ functor(Lit, _, Arity) },
create_dgoal(0, Arity, Lit).
create_dgoal(Arity, Arity, _Lit) --> !.
create_dgoal(I0, Arity, Lit) -->
{ I is I0+1, arg(I, Lit, A), mln_domain(I, Lit, TypeG, A) },
[ TypeG ],
create_dgoal(I, Arity, Lit).
2013-06-08 00:22:42 +01:00
cnf(V) --> { var(V) }, !,
[[V]].
cnf((A->B)) --> !,
cnf(-A+B).
cnf((A*B)) --> !,
cnf(A),
cnf(B).
cnf((A,B)) --> !,
cnf(A),
cnf(B).
cnf((-A)) --> !,
{ cnf(A, B, []) },
neg(B).
cnf((\+ A)) --> !,
{ cnf(A, B, []) },
neg(B).
cnf(A+B, Lf, L0) :- !,
cnf(A, LA, []),
cnf(B, LB, []),
foldl(or(LB), LA, Lf, L0).
cnf((A;B), Lf, L0) :- !,
cnf(A, LA, []),
cnf(B, LB, []),
foldl(or(LB), LA, Lf, L0).
cnf((A==B)) --> !,
cnf((A+ -B)),
cnf((B+ -A)).
cnf(xor(A,B)) --> !,
cnf(A+B),
cnf(-B + -A).
cnf(A) -->
[[A]].
or(LB, Disj, Lf, L0) :-
foldl( add(Disj), LB, Lf, L0).
add( Disj, El) -->
{ append(Disj, El, UnSort),
sort(UnSort, Els) },
[Els].
neg(Els) -->
{ maplist( neg, Els, Conjs) },
orl(Conjs).
neg(El, Conj) :-
maplist(neg2, El, Conj).
neg2(-X, [X]) :- !.
neg2(X, [-X]).
orl([C1,C2|C]) -->
{ foldl(or(C2), C1, C3, []) },
orl([C3|C]).
orl([Cs]) -->
Cs.
clean_cnf(CNF, NCNF) :-
maplist(sort, CNF, CNF1),
sort(CNF1, NCNF).