minimize_pred(b(truth,pred,Info),b(truth,pred,Info)).
minimize_pred(b(falsity,pred,Info),b(falsity,pred,Info)).
minimize_pred(b(Pred,pred,Info),Shrunken) :-
Pred =.. [Type,Arg] ,
member(Type,[negation,finite]) ,
prob_is_ground(Arg,Res) ,
% if argument is ground interpret predicate
(Res = true
-> pint(b(Pred,pred,Info),Value) ,
(Value = true
-> Shrunken = b(truth,pred,Info)
; Shrunken = b(falsity,pred,Info))
; (Type = negation
-> minimize_pred(Arg,NewArg)
; minimize_set_expr(Arg,NewArg)) ,
NewPred =.. [Type,NewArg] ,
Shrunken = b(NewPred,pred,Info)).
minimize_pred(b(exists(IDs,InnerPred),pred,Info),b(exists(IDs,NewInner),pred,Info)) :-
minimize_pred(InnerPred,NewInner).
minimize_pred(b(forall(IDs,Constraints,InnerPred),pred,Info),b(forall(IDs,NewConstraints,NewInner),pred,Info)) :-
minimize_pred(InnerPred,NewInner) ,
minimize_constraint_pred(Constraints,NewConstraints).
minimize_pred(b(Pred,pred,Info),Shrunken) :-
Pred =.. [Type,Arg1,Arg2] ,
member(Type,[conjunct,disjunct,implication,equivalence,equal,not_equal]) ,
prob_is_ground(Arg1,true) ,
prob_is_ground(Arg2,true) ,
pint(b(Pred,pred,Info),Value) ,
(Value = true
-> Shrunken = b(truth,pred,Info)
; Shrunken = b(falsity,pred,Info)).
minimize_pred(b(Pred,pred,Info),Shrunken) :-
Pred =.. [Type,Arg1,Arg2] ,
member(Type,[conjunct,disjunct,implication,equivalence,equal,not_equal]) ,
prob_is_ground(Arg1,Res1) ,
prob_is_ground(Arg2,Res2) ,
% hold boolean value and minimize predicate
(Res1 = true , Res2 = false
-> minimize_pred(Arg2,NewArg2) ,
NewExpr =.. [Type,Arg1,NewArg2] ,
Shrunken = b(NewExpr,pred,Info)
; Res1 = false , Res2 = true
-> minimize_pred(Arg1,NewArg1) ,
NewExpr =.. [Type,NewArg1,Arg2] ,
Shrunken = b(NewExpr,pred,Info)
; % minimize both expressions
minimize_pred(Arg1,NewArg1) ,
minimize_pred(Arg2,NewArg2) ,
NewExpr =.. [Type,NewArg1,NewArg2] ,
Shrunken = b(NewExpr,pred,Info)).
minimize_pred(b(Pred,pred,Info),Shrunken) :-
Pred =.. [Type,_,_] ,
member(Type,[member,not_member]) ,
pint(b(Pred,pred,Info),Value) ,
(Value = true
-> Shrunken = b(truth,pred,Info)
; Shrunken = b(falsity,pred,Info)).
minimize_pred(b(identifier(Name),Type,Info),b(identifier(Name),Type,Info)).
minimize_pred(b(Pred,pred,Info),Shrunken) :-
Pred =.. [_,Arg1,Arg2] ,
prob_is_ground(Arg1,true) ,
prob_is_ground(Arg2,true) ,
pint(b(Pred,pred,Info),Value) ,
(Value = true
-> Shrunken = b(truth,pred,Info)
; Shrunken = b(falsity,pred,Info)).
minimize_pred(b(Pred,pred,Info),Shrunken) :-
Pred =.. [Type,Expr1,Expr2] ,
prob_is_ground(Expr1,Res1) , prob_is_ground(Expr2,Res2) ,
% hold boolean value and minimize integer expressions
( Res1 = true , Res2 = false
-> (shrink(prob_ast_expr(_),Expr2,NewArg2) ; shrink(prob_ast_pred(_),Expr2,NewArg2)) ,
NewExpr =.. [Type,Expr1,NewArg2] ,
Shrunken = b(NewExpr,pred,Info)
; Res1 = false , Res2 = true
-> (shrink(prob_ast_expr(_),Expr1,NewArg1) ; shrink(prob_ast_pred(_),Expr1,NewArg1)) ,
NewExpr =.. [Type,NewArg1,Expr2] ,
Shrunken = b(NewExpr,pred,Info)
; % minimize both expressions
(shrink(prob_ast_expr(_),Expr1,NewArg1) ; shrink(prob_ast_pred(_),Expr1,NewArg1)) ,
(shrink(prob_ast_expr(_),Expr2,NewArg2) ; shrink(prob_ast_pred(_),Expr2,NewArg2)) ,
NewExpr =.. [Type,NewArg1,NewArg2] ,
Shrunken = b(NewExpr,pred,Info)).