2010-03-18 15:11:21 +00:00
|
|
|
/*==============================================================================
|
|
|
|
* LPAD and CP-Logic reasoning suite
|
|
|
|
* File best.pl
|
|
|
|
* Goal oriented interpreter for LPADs based on SLDNF
|
|
|
|
* Copyright (c) 2009, Stefano Bragaglia
|
|
|
|
*============================================================================*/
|
|
|
|
|
|
|
|
:- dynamic rule/4, def_rule/2.
|
|
|
|
|
|
|
|
/* EXTERNAL FILE
|
|
|
|
* -------------
|
|
|
|
* The following libraries are required by the program to work fine.
|
|
|
|
*/
|
|
|
|
:- use_module(library(lists)).
|
|
|
|
:- use_module(library(system)).
|
|
|
|
:- use_module(library(ugraphs)).
|
|
|
|
:- use_module(params).
|
2010-03-21 10:49:19 +00:00
|
|
|
:- use_module(tptree_lpad).
|
2010-03-18 15:11:21 +00:00
|
|
|
:- use_module(utility).
|
|
|
|
|
|
|
|
% :- source.
|
|
|
|
% :- yap_flag(single_var_warnings, on).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* SOLVING PREDICATES
|
|
|
|
* ------------------
|
|
|
|
* The predicates in this section solve any given problem with several class of
|
|
|
|
* algorithms.
|
|
|
|
*
|
|
|
|
* Note: the original predicates (no more need and eligible to be deleted) have
|
|
|
|
* been moved to the end of the file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* solve(Goals, Prob, ResTime, BddTime)
|
|
|
|
* ------------------------------------
|
|
|
|
* This predicate computes the probability of a given list of goals using an
|
|
|
|
* iterative deepening, probability bounded algorithm.
|
|
|
|
* It also returns the number of handled BDDs and the CPUTime spent performing
|
|
|
|
* resolution and spent handling the BDDs.
|
|
|
|
*
|
|
|
|
* Note: when their derivation is cut, negative goals are added to the head of
|
|
|
|
* the goals' list to be solved during the following iteration.
|
|
|
|
*
|
|
|
|
* INPUT
|
|
|
|
* - GoalsList: given list of goal to work on. It can contains variables: the
|
|
|
|
* predicate returns in backtracking all the solutions and their equivalent
|
|
|
|
* lower and upper bound probability.
|
|
|
|
*
|
|
|
|
* OUTPUT
|
|
|
|
* - Prob: resulting lower bound probability for the given list of goals.
|
|
|
|
* - ResTime: CPU time spent on performing resolution.
|
|
|
|
* - BddTime: CPU time spent on handling BDDs.
|
|
|
|
*/
|
|
|
|
solve(Goals, Prob, ResTime, BddTime) :-
|
|
|
|
setting(k, K),
|
|
|
|
setting(prob_step, ProbStep),
|
|
|
|
ProbStepLog is log(ProbStep),
|
|
|
|
% NB: log(1.0) == 0.0 !!!
|
|
|
|
bestk([0.0-0.0-([], [], Goals)], K, ProbStepLog, Prob, ResTime, BddTime).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* bestk(GoalsList, K, ProbStep, Prob, ResTime, BddTime)
|
|
|
|
* -----------------------------------------------------
|
|
|
|
* This recursive supporting predicate performs resolution for current iteration,
|
|
|
|
* sticks with the best complete solutions only and considers their equivalent
|
|
|
|
* BDD to compute their probability.
|
|
|
|
*
|
|
|
|
* INPUT
|
|
|
|
* - GoalsList: given list of goal to work on.
|
|
|
|
* - K: number of solution to consider.
|
|
|
|
* - ProbStep: value used to update the probability bound.
|
|
|
|
*
|
|
|
|
* OUTPUT
|
|
|
|
* - Prob: resulting probability (actaully a lower bound) for the given list of goals.
|
|
|
|
* - ResTime: cpu time spent on performing resolution.
|
|
|
|
* - BddTime: cpu time spent on handling BDDs.
|
|
|
|
*/
|
|
|
|
bestk(GoalsList, K, ProbStep, Prob, ResTime, BddTime) :-
|
|
|
|
% Resetting the clocks...
|
|
|
|
statistics(walltime, [_, _]),
|
|
|
|
|
|
|
|
% Performing resolution...
|
|
|
|
main(GoalsList, K, ProbStep, BestK),
|
|
|
|
|
|
|
|
% Taking elapsed times...
|
|
|
|
statistics(walltime, [_, ElapResTime]),
|
|
|
|
ResTime is ElapResTime/1000,
|
|
|
|
|
|
|
|
% Building and solving equivalent bdds...
|
|
|
|
init_ptree(1),
|
|
|
|
insert_full_ptree(BestK, 1),
|
|
|
|
bdd_ptree_map(1, 'bdd.txt', 'bdd.par', 'bdd.map'),
|
|
|
|
delete_ptree(1),
|
|
|
|
run_file('bdd.txt','bdd.par', Temp),
|
|
|
|
(Temp == timeout ->
|
|
|
|
Prob is -1.0;
|
|
|
|
Prob is Temp),
|
|
|
|
|
|
|
|
% Taking elapsed times...
|
|
|
|
statistics(walltime, [_, ElapBddTime]),
|
|
|
|
BddTime is (ElapBddTime / 1000).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* main(Goals, K, ProbStep, Best)
|
|
|
|
* ------------------------------
|
|
|
|
* This tail recursive predicate returns the Best K complete solutions to the
|
|
|
|
* given Goals. The probability bound is dinamically computed at each iteration.
|
|
|
|
*
|
|
|
|
* INPUT
|
|
|
|
* - Goals: list of goals to achive.
|
|
|
|
* - K: desired number of solutions.
|
|
|
|
* - ProbStep: value used to update the probability bound.
|
|
|
|
*
|
|
|
|
* OUTPUT
|
|
|
|
* - Best: list of best solutions (at most k).
|
|
|
|
*/
|
|
|
|
main(Goals, K, ProbStep, Best) :-
|
|
|
|
K > 0,
|
|
|
|
main(Goals, ProbStep, K, 0.0, [], Best).
|
|
|
|
|
|
|
|
main([], _ProbStep, _Left, _Worst, Best, Best).
|
|
|
|
|
|
|
|
main(Goals, ProbStep, Left0, Worst0, Best0, Best1) :-
|
|
|
|
findall(Prob1-Bound-(Gnd1, Var1, Goals1),
|
|
|
|
(member(Prob0-Bound0-(Gnd0, Var0, Goals0), Goals), Bound is Bound0+ ProbStep, explore(Bound, Prob0-(Gnd0, Var0, Goals0), Prob1-(Gnd1, Var1, Goals1))),
|
|
|
|
Found),
|
|
|
|
%% sepkeepbest(Found, Left0, Left2, Worst0, Worst2, Best0, Best2, [], Incomplete),
|
|
|
|
separate_main(Found, [], Complete, [], _UpperList, [], Incomplete),
|
|
|
|
keepbest(Complete, Left0, Left2, Worst0, Worst2, Best0, Best2),
|
|
|
|
main(Incomplete, ProbStep, Left2, Worst2, Best2, Best1).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* sepkeepbest(Found, Left0, Left1, Worst0, Worst1, List0, List1, Next0, Next1)
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
* This tail recursive predicate analyzes the given list of solutions found and
|
|
|
|
* returns the list of (K at most) best complete solutions and the whole list of
|
|
|
|
* incomplete solutions for a full B&B behaviour.
|
|
|
|
* The given worst value permits some optimization, such as immediate skipping
|
|
|
|
* of very bad solutions.
|
|
|
|
*
|
|
|
|
* INPUT
|
|
|
|
* - Found: list of solutions found.
|
|
|
|
* - Left0: actual amount of items still needed to have K solutions.
|
|
|
|
* - Worst0: value of the actual worst complete solution kept.
|
|
|
|
* - List0: actual list of best complete solutions.
|
|
|
|
* - Next0: actual list of incomplete solutions.
|
|
|
|
*
|
|
|
|
* OUTPUT
|
|
|
|
* - Left1: final amount of items still needed to have K solutions.
|
|
|
|
* - Worst1: value of the final worst complete solution kept.
|
|
|
|
* - List1: final list of best complete solutions.
|
|
|
|
* - Next1: final list of incomplete solutions.
|
|
|
|
*/
|
|
|
|
sepkeepbest([], Left, Left, Worst, Worst, List, List, Next, Next) :- !.
|
|
|
|
%% Closing condition: stop if no more results (current values are now final values).
|
|
|
|
|
|
|
|
sepkeepbest([Prob0-(_Gnd0, [], [])|Tail], 0, Left1, Worst0, Worst1, List0, List1, Next0, Next1) :-
|
|
|
|
Prob0 =< Worst0, !,
|
|
|
|
sepkeepbest(Tail, 0, Left1, Worst0, Worst1, List0, List1, Next0, Next1).
|
|
|
|
|
|
|
|
sepkeepbest([Prob0-(Gnd0, [], [])|Tail], 0, Left1, Worst0, Worst1, List0, List1, Next0, Next1) :-
|
|
|
|
Prob0 > Worst0, !,
|
|
|
|
discard(Prob0-(Gnd0, [], []), List0, List2, Worst2),
|
|
|
|
sepkeepbest(Tail, 0, Left1, Worst2, Worst1, List2, List1, Next0, Next1).
|
|
|
|
|
|
|
|
sepkeepbest([Prob0-(Gnd0, [], [])|Tail], Left0, Left1, Worst0, Worst1, List0, List1, Next0, Next1) :- !,
|
|
|
|
insert(Prob0-(Gnd0, [], []), List0, Worst0, List2, Worst2),
|
|
|
|
Left2 is Left0 - 1,
|
|
|
|
sepkeepbest(Tail, Left2, Left1, Worst2, Worst1, List2, List1, Next0, Next1).
|
|
|
|
|
|
|
|
sepkeepbest([Prob0-(Gnd0, Var0, Goals)|Tail], Left0, Left1, Worst0, Worst1, List0, List1, Next0, [Prob1-(Gnd1, Var1, Goals)|Next1]) :-
|
|
|
|
get_groundc(Var0, Gnd2, Var1, 1.0, Prob2),
|
|
|
|
append(Gnd0, Gnd2, Gnd1),
|
|
|
|
Prob1 is Prob0 + log(Prob2),
|
|
|
|
sepkeepbest(Tail, Left0, Left1, Worst0, Worst1, List0, List1, Next0, Next1).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* separate(List, Low, Up, Next)
|
|
|
|
* -----------------------------
|
|
|
|
* This tail recursive predicate parses the input list and builds the list for
|
|
|
|
* the lower bound, the upper bound and the pending goals.
|
|
|
|
* The upper bound list contains both the items of the lower bound list and the
|
|
|
|
* incomplete ones.
|
|
|
|
*
|
|
|
|
* INPUT
|
|
|
|
* - List: input list.
|
|
|
|
*
|
|
|
|
* OUTPUT
|
|
|
|
* - Low: list for lower bound.
|
|
|
|
* - Up: list for upper bound.
|
|
|
|
* - Next: list of pending goals.
|
|
|
|
*/
|
|
|
|
separate(List, Low, Up, Next) :-
|
|
|
|
%% Polarization: initial low, up and next lists are empty.
|
|
|
|
separate(List, [], Low, [], Up, [], Next).
|
|
|
|
|
|
|
|
separate([], Low, Low, Up, Up, Next, Next) :- !.
|
|
|
|
%% Closing condition: stop if no more results (current lists are now final lists).
|
|
|
|
|
|
|
|
separate([Prob0-(Gnd0, [], [])|Tail], Low0, [Gnd0|Low1], Up0, [Prob0-(Gnd0, [], [])|Up1], Next0, Next1) :- !,
|
|
|
|
separate(Tail, Low0, Low1, Up0, Up1, Next0, Next1).
|
|
|
|
|
|
|
|
separate([Prob0-(Gnd0, Var0, Goals)|Tail], Low0, Low1, Up0, [Prob0-(Gnd0, Var0, Goals)|Up1], Next0, [Prob0-(Gnd0, Var0, Goals)|Next1]) :-
|
|
|
|
separate(Tail, Low0, Low1, Up0, Up1, Next0, Next1).
|
|
|
|
|
|
|
|
separate_main([], Low, Low, Up, Up, Next, Next) :- !.
|
|
|
|
%% Closing condition: stop if no more results (current lists are now final lists).
|
|
|
|
|
|
|
|
separate_main([Prob0-_Bound0-(Gnd0, [], [])|Tail], Low0, [Prob0-(Gnd0, [], [])|Low1], Up0, [Prob0-(Gnd0, [], [])|Up1], Next0, Next1) :- !,
|
|
|
|
separate_main(Tail, Low0, Low1, Up0, Up1, Next0, Next1).
|
|
|
|
|
|
|
|
separate_main([Prob0-Bound0-(Gnd0, Var0, Goals)|Tail], Low0, Low1, Up0, [Prob0-Bound0-(Gnd0, Var0, Goals)|Up1], Next0, [Prob0-Bound0-(Gnd0, Var0, Goals)|Next1]) :-
|
|
|
|
separate_main(Tail, Low0, Low1, Up0, Up1, Next0, Next1).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* explore(ProbBound, Prob0-(Gnd0, Var0, Goals0), Prob1-(Gnd1, Var1, Goals1))
|
|
|
|
* --------------------------------------------------------------------------
|
|
|
|
* This tail recursive predicate reads current explanation and returns the
|
|
|
|
* explanation after the current iteration without dropping below the given
|
|
|
|
* probability bound.
|
|
|
|
*
|
|
|
|
* INPUT
|
|
|
|
* - ProbBound: the desired probability bound;
|
|
|
|
* - Prob0-(Gnd0, Var0, Goals0): current explanation
|
|
|
|
* - Gnd0: list of current ground choices,
|
|
|
|
* - Var0: list of current non-ground choices,
|
|
|
|
* - Prob0: probability of Gnd0,
|
|
|
|
* - Goals0: list of current goals.
|
|
|
|
*
|
|
|
|
* OUTPUT
|
|
|
|
* - Prob1-(Gnd1, Var1, Prob1, Goals1): explanation after current iteration
|
|
|
|
* - Gnd1: list of final ground choices,
|
|
|
|
* - Var1: list of final non-ground choices,
|
|
|
|
* - Prob1: probability of Gnd1,
|
|
|
|
* - Goals1: list of final goals.
|
|
|
|
*/
|
|
|
|
explore(_ProbBound, Prob-(Gnd, Var, []), Prob-(Gnd, Var, [])) :- !.
|
|
|
|
%% Closing condition: stop if no more goals (input values are output values).
|
|
|
|
|
|
|
|
explore(ProbBound, Prob-(Gnd, Var, Goals), Prob-(Gnd, Var, Goals)) :-
|
|
|
|
%% Closing condition: stop if bound has been reached (input values are output values).
|
|
|
|
Prob =< ProbBound, !.
|
|
|
|
|
|
|
|
% Negation, builtin
|
|
|
|
explore(ProbBound, Prob0-(Gnd0, Var0, [\+ Head|Tail]), Prob1-(Gnd1, Var1, Goals1)) :-
|
|
|
|
builtin(Head), !,
|
|
|
|
call((\+ Head)),
|
|
|
|
explore(ProbBound, Prob0-(Gnd0, Var0, Tail), Prob1-(Gnd1, Var1, Goals1)).
|
|
|
|
%% Recursive call: consider next goal (building next values)
|
|
|
|
|
|
|
|
% Negation
|
|
|
|
explore(ProbBound, Prob0-(Gnd0, Var0, [\+ Head|Tail]), Prob1-(Gnd1, Var1, Goals1)) :- !,
|
|
|
|
list2and(HeadList, Head), % ...
|
|
|
|
findall(Prob-(Gnd, Var, CurrentGoals), explore(ProbBound, 0.0-([], [], HeadList), Prob-(Gnd, Var, CurrentGoals)), List) ->
|
|
|
|
separate(List, [], LowerBound, [], _UpperBound, [], PendingGoals),
|
|
|
|
(PendingGoals \= [] ->
|
|
|
|
Var2 = Var0,
|
|
|
|
Gnd2 = Gnd0,
|
|
|
|
Goals1 = [\+ Head|Goals],
|
|
|
|
explore(ProbBound, Prob0-(Gnd2, Var2, Tail), Prob1-(Gnd1, Var1, Goals));
|
|
|
|
%% Recursive call: consider next goal (building next values)
|
|
|
|
|
|
|
|
choose_clausesc(Gnd0, Var0, LowerBound, Var),
|
|
|
|
get_prob(Var, 1, Prob),
|
|
|
|
append(Gnd0, Var, Gnd2),
|
|
|
|
Prob2 is Prob0 + log(Prob),
|
|
|
|
explore(ProbBound, Prob2-(Gnd2, [], Tail), Prob1-(Gnd1, Var1, Goals1))).
|
|
|
|
%% Recursive call: consider next goal (building next values)
|
|
|
|
|
|
|
|
% Main, builtin
|
|
|
|
explore(ProbBound, Prob0-(Gnd0, Var0, [Head|Tail]), Prob1-(Gnd1, Var1, Goals1)) :-
|
|
|
|
builtin(Head), !,
|
|
|
|
call(Head),
|
|
|
|
explore(ProbBound, Prob0-(Gnd0, Var0, Tail), Prob1-(Gnd1, Var1, Goals1)).
|
|
|
|
% Recursive call: consider next goal (building next values)
|
|
|
|
|
|
|
|
% Main, def_rule
|
|
|
|
explore(ProbBound, Prob0-(Gnd0, Var0, [Head|Tail]), Prob1-(Gnd1, Var1, Goals1)) :-
|
|
|
|
def_rule(Head, Goals0),
|
|
|
|
append(Goals0, Tail, Goals2),
|
|
|
|
explore(ProbBound, Prob0-(Gnd0, Var0, Goals2), Prob1-(Gnd1, Var1, Goals1)).
|
|
|
|
% Recursive call: consider next goal (building next values)
|
|
|
|
|
|
|
|
% Main, find_rulec
|
|
|
|
explore(ProbBound, Prob0-(Gnd0, Var0, [Head|Tail]), Prob1-(Gnd1, Var1, Goals1)) :-
|
|
|
|
find_rulec(Head, (R, S, N), Goals, Var0, _Prob),
|
|
|
|
explore_pres(ProbBound, R, S, N, Goals, Prob0-(Gnd0, Var0, Tail), Prob1-(Gnd1, Var1, Goals1)).
|
|
|
|
|
|
|
|
explore_pres(ProbBound, R, S, N, Goals, Prob0-(Gnd0, Var0, Goals0), Prob1-(Gnd1, Var1, Goals)) :-
|
|
|
|
(member_eq((N, R, S), Var0);
|
|
|
|
member_eq((N, R, S), Gnd0)), !,
|
|
|
|
append(Goals, Goals0, Goals2),
|
|
|
|
explore(ProbBound, Prob0-(Gnd0, Var0, Goals2), Prob1-(Gnd1, Var1, Goals)).
|
|
|
|
% Recursive call: consider next goal (building next values)
|
|
|
|
|
|
|
|
explore_pres(ProbBound, R, S, N, Goals, Prob0-(Gnd0, Var0, Goals0), Prob1-(Gnd1, Var1, Goals1)) :-
|
|
|
|
append(Var0, [(N, R, S)], Var),
|
|
|
|
append(Goals, Goals0, Goals2),
|
|
|
|
get_prob(Var, 1, Prob),
|
|
|
|
append(Gnd0, Var, Gnd2),
|
|
|
|
Prob2 is Prob0 + log(Prob),
|
|
|
|
explore(ProbBound, Prob2-(Gnd2, [], Goals2), Prob1-(Gnd1, Var1, Goals1)).
|
|
|
|
% Recursive call: consider next goal (building next values)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* keepbest(List, K, BestK)
|
|
|
|
* ------------------------
|
|
|
|
* This tail recursive predicate parses the given list of quads and returns the
|
|
|
|
* list of its best k quads. If the given list of quads contains less than k
|
|
|
|
* items, the predicate returns them all.
|
|
|
|
*
|
|
|
|
* INPUT
|
|
|
|
* - List: list of quads to parse.
|
|
|
|
* - K: desired number of quads.
|
|
|
|
*
|
|
|
|
* OUTPUT
|
|
|
|
* - BestK: final list of (at most) best k quads.
|
|
|
|
*/
|
|
|
|
keepbest(List, K, BestK) :-
|
|
|
|
K > 0,
|
|
|
|
keepbest(List, K, _Left, 0.0, _Worst, [], BestK).
|
|
|
|
|
|
|
|
/*keepbest([], _Left, _Worst, List, List).
|
|
|
|
|
|
|
|
keepbest([Prob-(_Gnd, _Var, _Goals)|Tail], 0, Worst, List0, List1) :-
|
|
|
|
Prob =< Worst, !,
|
|
|
|
keepbest(Tail, 0, Worst, List0, List1).
|
|
|
|
|
|
|
|
keepbest([Prob-(Gnd, Var, Goals)|Tail], 0, Worst, List0, List1) :-
|
|
|
|
Prob > Worst, !,
|
|
|
|
discard(Prob-(Gnd, Var, Goals), List0, List2, Worst2),
|
|
|
|
keepbest(Tail, 0, Worst2, List2, List1).
|
|
|
|
|
|
|
|
keepbest([Prob-(Gnd, Var, Goals)|Tail], Left, Worst, List0, List1) :-
|
|
|
|
insert(Prob-(Gnd, Var, Goals), List0, Worst, List2, Worst2),
|
|
|
|
Left2 is Left - 1,
|
|
|
|
keepbest(Tail, Left2, Worst2, List2, List1).*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
keepbest([], Left, Left, Worst, Worst, List, List).
|
|
|
|
|
|
|
|
keepbest([Prob-(_Gnd, _Var, _Goals)|Tail], 0, Left1, Worst0, Worst1, List0, List1) :-
|
|
|
|
Prob =< Worst0, !,
|
|
|
|
keepbest(Tail, 0, Left1, Worst0, Worst1, List0, List1).
|
|
|
|
|
|
|
|
keepbest([Prob-(Gnd, Var, Goals)|Tail], 0, Left1, Worst0, Worst1, List0, List1) :-
|
|
|
|
Prob > Worst0, !,
|
|
|
|
discard(Prob-(Gnd, Var, Goals), List0, List2, Worst2),
|
|
|
|
keepbest(Tail, 0, Left1, Worst2, Worst1, List2, List1).
|
|
|
|
|
|
|
|
keepbest([Prob-(Gnd, Var, Goals)|Tail], Left0, Left1, Worst0, Worst1, List0, List1) :-
|
|
|
|
insert(Prob-(Gnd, Var, Goals), List0, Worst0, List2, Worst2),
|
|
|
|
Left2 is Left0 - 1,
|
|
|
|
keepbest(Tail, Left2, Left1, Worst2, Worst1, List2, List1).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* insert(Prob-(Gnd, Var, Goals), Sorted0, Worst0, Sorted1, Worst1)
|
|
|
|
* ----------------------------------------------------------------
|
|
|
|
* This tail recursive predicate inserts the given quad into the given sorted
|
|
|
|
* list and returns the final sorted list. The input list must be sorted.
|
|
|
|
* It also updates the prob value of the worst quad.
|
|
|
|
*
|
|
|
|
* INPUT
|
|
|
|
* - Prob-(Gnd, Var, Goals): quad to insert.
|
|
|
|
* - Sorted0: sorted list to insert the quad into.
|
|
|
|
* - Worst0: current worst prob value.
|
|
|
|
*
|
|
|
|
* OUTPUT
|
|
|
|
* - Sorted1: the final sorted list.
|
|
|
|
* - Worst1: the final worst prob value.
|
|
|
|
*/
|
|
|
|
insert(Prob-(Gnd, Var, Goals), [], _Worst, [Prob-(Gnd, Var, Goals)], Prob).
|
|
|
|
|
|
|
|
insert(Prob-(Gnd, Var, Goals), [Prob_i-(Gnd_i, Var_i, Goals_i)|Tail], Worst, [Prob-(Gnd, Var, Goals), Prob_i-(Gnd_i, Var_i, Goals_i)|Tail], Worst) :-
|
|
|
|
Prob >= Prob_i, !.
|
|
|
|
|
|
|
|
insert(Prob-(Gnd, Var, Goals), [Prob_i-(Gnd_i, Var_i, Goals_i)|Tail], Worst0, [Prob_i-(Gnd_i, Var_i, Goals_i)|Next], Worst1) :-
|
|
|
|
Prob < Prob_i, !,
|
|
|
|
insert(Prob-(Gnd, Var, Goals), Tail, Worst0, Next, Worst1).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* discard(Prob-(Gnd, Var, Goals), Sorted0, Sorted1, Worst)
|
|
|
|
* --------------------------------------------------------
|
|
|
|
* This tail recursive predicate inserts the given quad into the given sorted
|
|
|
|
* list, removes the last quad from it and returns the final sorted list.
|
|
|
|
* The given sorted list contains at least one quad and must be sorted.
|
|
|
|
* Previous worst prob value is not needed because it necessarely changes and
|
|
|
|
* the new value is not known in advance.
|
|
|
|
* It also updates the prob value of the worst quad.
|
|
|
|
*
|
|
|
|
* INPUT
|
|
|
|
* - Prob-(Gnd, Var, Goals): quad to insert.
|
|
|
|
* - Sorted0: sorted list to insert the quad into.
|
|
|
|
*
|
|
|
|
* OUTPUT
|
|
|
|
* - Sorted1: the final sorted list.
|
|
|
|
* - Worst: the final worst prob value.
|
|
|
|
*/
|
|
|
|
discard(Prob-(Gnd, Var, Goals), [_Prob_i-(_Gnd_i, _Var_i, _Goals_i)], [Prob-(Gnd, Var, Goals)], Prob) :- !.
|
|
|
|
|
|
|
|
discard(Prob-(Gnd, Var, Goals), [Prob_i-(Gnd_i, Var_i, Goals_i), Prob_l-(Gnd_l, Var_l, Goals_l)|Tail], [Prob-(Gnd, Var, Goals)|Next], Worst) :-
|
|
|
|
Prob >= Prob_i, !,
|
|
|
|
discard(Prob_i-(Gnd_i, Var_i, Goals_i), [Prob_l-(Gnd_l, Var_l, Goals_l)|Tail], Next, Worst).
|
|
|
|
|
|
|
|
discard(Prob-(Gnd, Var, Goals), [Prob_i-(Gnd_i, Var_i, Goals_i), Prob_l-(Gnd_l, Var_l, Goals_l)|Tail], [Prob_i-(Gnd_i, Var_i, Goals_i)|Next], Worst) :-
|
|
|
|
Prob < Prob_i, !,
|
|
|
|
discard(Prob-(Gnd, Var, Goals), [Prob_l-(Gnd_l, Var_l, Goals_l)|Tail], Next, Worst).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* eval_lower(Number, Prob)
|
|
|
|
* ------------------------
|
|
|
|
* This predicate evaluates if there are proofs for the lower bound by
|
|
|
|
* running an external command (BDD resolution via files).
|
|
|
|
*/
|
|
|
|
eval_lower(Number, Prob) :-
|
|
|
|
low(Number, Prob).
|
|
|
|
|
|
|
|
eval_lower(Number, ProbLow) :-
|
|
|
|
Number > 0,
|
|
|
|
low(OldNumber, _),
|
|
|
|
Number \= OldNumber,
|
|
|
|
bdd_ptree_map(1, 'bddl.txt', 'bddl.par', 'bddl.map'),
|
|
|
|
run_file('bddl.txt', 'bddl.par', NewProbLow),
|
|
|
|
(NewProbLow = timeout ->
|
|
|
|
low(_, ProbLow);
|
|
|
|
|
|
|
|
ProbLow = NewProbLow,
|
|
|
|
retract(low(_, _)),
|
|
|
|
assert(low(Number, ProbLow))).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* eval_upper(Number, Prob)
|
|
|
|
* ------------------------
|
|
|
|
* This predicate evaluates if there are proofs for the upper bound by
|
|
|
|
* running an external command (BDD resolution via files).
|
|
|
|
*/
|
|
|
|
eval_upper(0, ProbUp) :- !,
|
|
|
|
low(_, ProbUp).
|
|
|
|
|
|
|
|
eval_upper(_Number, ProbUp) :-
|
|
|
|
bdd_ptree_map(3, 'bddu.txt', 'bddu.par', 'bddu.map'),
|
|
|
|
run_file('bddu.txt', 'bddu.par', NewProbUp),
|
|
|
|
(NewProbUp = timeout->
|
|
|
|
up(ProbUp);
|
|
|
|
ProbUp = NewProbUp,
|
|
|
|
retract(up(_)),
|
|
|
|
assert(up(ProbUp))).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* run_file(BDDFile, BDDParFile, Prob)
|
|
|
|
* -----------------------------------
|
|
|
|
* This predicate calls for the resolution of a BDD via file.
|
|
|
|
*/
|
|
|
|
run_file(BDDFile, BDDParFile, Prob) :-
|
|
|
|
ResultFile = 'result.txt',
|
|
|
|
library_directory(Dir),
|
|
|
|
setting(timeout, BDDTime),
|
|
|
|
(BDDTime = no ->
|
|
|
|
atomic_concat([Dir, '/LPADBDD -l ', BDDFile, ' -i ', BDDParFile,' > ', ResultFile], Command);
|
|
|
|
atomic_concat([Dir, '/LPADBDD -l ', BDDFile, ' -i ', BDDParFile,' -t ', BDDTime,' > ', ResultFile], Command)),
|
|
|
|
|
|
|
|
%statistics(walltime,_),
|
|
|
|
|
|
|
|
shell(Command, Return),
|
|
|
|
(Return =\= 0 ->
|
|
|
|
Status = timeout,
|
|
|
|
Prob = Status;
|
|
|
|
|
|
|
|
see(ResultFile),
|
|
|
|
read(elapsed_construction(_TimeConstruction)),
|
|
|
|
read(probability(Prob)),
|
|
|
|
read(elapsed_traversing(_TimeTraversing)),
|
|
|
|
seen,
|
|
|
|
|
|
|
|
%write(probability(Prob)),nl,
|
|
|
|
%read(_),
|
|
|
|
%delete_file(ResultFile),
|
|
|
|
|
|
|
|
Status = ok
|
|
|
|
% format("Construction time ~f traversing time ~f~Number",[TimeConstruction, TimeTraversing])
|
|
|
|
).
|
|
|
|
|
|
|
|
%statistics(walltime,[_,E3]),
|
|
|
|
%format(user,'~w ms BDD processing~Number',[E3]),
|
|
|
|
% format("Status ~a~Number",[Status]).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* insert_full_ptree([Head|Tail], Trie)
|
|
|
|
* ------------------------------------
|
|
|
|
* This predicate inserts the ground part of the given list in a trie.
|
|
|
|
*/
|
|
|
|
insert_full_ptree([], _Trie).
|
|
|
|
|
|
|
|
insert_full_ptree([_Prob-(Gnd, _Var, _Goals)|Tail], Trie) :-
|
|
|
|
reverse(Gnd, Gnd1),
|
|
|
|
insert_ptree(Gnd1, Trie),
|
|
|
|
insert_full_ptree(Tail, Trie).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* insert_list_ptree([Head|Tail], Trie)
|
|
|
|
* ------------------------------------
|
|
|
|
* This predicate inserts the given list in a trie.
|
|
|
|
*/
|
|
|
|
insert_list_ptree([], _Trie).
|
|
|
|
|
|
|
|
insert_list_ptree([Head|Tail], Trie) :-
|
|
|
|
reverse(Head, Head1),
|
|
|
|
insert_ptree(Head1, Trie),
|
|
|
|
insert_list_ptree(Tail, Trie).
|
|
|
|
|
|
|
|
|