1%%% -*- Mode: Prolog; -*-
2
3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4%
5%  $Date: 2011-11-28 14:41:26 +0100 (Mon, 28 Nov 2011) $
6%  $Revision: 6764 $
7%
8%  This file is part of ProbLog
9%  http://dtai.cs.kuleuven.be/problog
10%
11%  ProbLog was developed at Katholieke Universiteit Leuven
12%
13%  Copyright 2008, 2009, 2010
14%  Katholieke Universiteit Leuven
15%
16%  Main authors of this file:
17%  Theofrastos Mantadelis, Dimitar Sht. Shterionov
18%
19%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20%
21% Artistic License 2.0
22%
23% Copyright (c) 2000-2006, The Perl Foundation.
24%
25% Everyone is permitted to copy and distribute verbatim copies of this
26% license document, but changing it is not allowed.  Preamble
27%
28% This license establishes the terms under which a given free software
29% Package may be copied, modified, distributed, and/or
30% redistributed. The intent is that the Copyright Holder maintains some
31% artistic control over the development of that Package while still
32% keeping the Package available as open source and free software.
33%
34% You are always permitted to make arrangements wholly outside of this
35% license directly with the Copyright Holder of a given Package. If the
36% terms of this license do not permit the full use that you propose to
37% make of the Package, you should contact the Copyright Holder and seek
38% a different licensing arrangement.  Definitions
39%
40% "Copyright Holder" means the individual(s) or organization(s) named in
41% the copyright notice for the entire Package.
42%
43% "Contributor" means any party that has contributed code or other
44% material to the Package, in accordance with the Copyright Holder's
45% procedures.
46%
47% "You" and "your" means any person who would like to copy, distribute,
48% or modify the Package.
49%
50% "Package" means the collection of files distributed by the Copyright
51% Holder, and derivatives of that collection and/or of those files. A
52% given Package may consist of either the Standard Version, or a
53% Modified Version.
54%
55% "Distribute" means providing a copy of the Package or making it
56% accessible to anyone else, or in the case of a company or
57% organization, to others outside of your company or organization.
58%
59% "Distributor Fee" means any fee that you charge for Distributing this
60% Package or providing support for this Package to another party. It
61% does not mean licensing fees.
62%
63% "Standard Version" refers to the Package if it has not been modified,
64% or has been modified only in ways explicitly requested by the
65% Copyright Holder.
66%
67% "Modified Version" means the Package, if it has been changed, and such
68% changes were not explicitly requested by the Copyright Holder.
69%
70% "Original License" means this Artistic License as Distributed with the
71% Standard Version of the Package, in its current version or as it may
72% be modified by The Perl Foundation in the future.
73%
74% "Source" form means the source code, documentation source, and
75% configuration files for the Package.
76%
77% "Compiled" form means the compiled bytecode, object code, binary, or
78% any other form resulting from mechanical transformation or translation
79% of the Source form.
80%
81%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82%
83% Permission for Use and Modification Without Distribution
84%
85% (1) You are permitted to use the Standard Version and create and use
86% Modified Versions for any purpose without restriction, provided that
87% you do not Distribute the Modified Version.
88%
89% Permissions for Redistribution of the Standard Version
90%
91% (2) You may Distribute verbatim copies of the Source form of the
92% Standard Version of this Package in any medium without restriction,
93% either gratis or for a Distributor Fee, provided that you duplicate
94% all of the original copyright notices and associated disclaimers. At
95% your discretion, such verbatim copies may or may not include a
96% Compiled form of the Package.
97%
98% (3) You may apply any bug fixes, portability changes, and other
99% modifications made available from the Copyright Holder. The resulting
100% Package will still be considered the Standard Version, and as such
101% will be subject to the Original License.
102%
103% Distribution of Modified Versions of the Package as Source
104%
105% (4) You may Distribute your Modified Version as Source (either gratis
106% or for a Distributor Fee, and with or without a Compiled form of the
107% Modified Version) provided that you clearly document how it differs
108% from the Standard Version, including, but not limited to, documenting
109% any non-standard features, executables, or modules, and provided that
110% you do at least ONE of the following:
111%
112% (a) make the Modified Version available to the Copyright Holder of the
113% Standard Version, under the Original License, so that the Copyright
114% Holder may include your modifications in the Standard Version.  (b)
115% ensure that installation of your Modified Version does not prevent the
116% user installing or running the Standard Version. In addition, the
117% modified Version must bear a name that is different from the name of
118% the Standard Version.  (c) allow anyone who receives a copy of the
119% Modified Version to make the Source form of the Modified Version
120% available to others under (i) the Original License or (ii) a license
121% that permits the licensee to freely copy, modify and redistribute the
122% Modified Version using the same licensing terms that apply to the copy
123% that the licensee received, and requires that the Source form of the
124% Modified Version, and of any works derived from it, be made freely
125% available in that license fees are prohibited but Distributor Fees are
126% allowed.
127%
128% Distribution of Compiled Forms of the Standard Version or
129% Modified Versions without the Source
130%
131% (5) You may Distribute Compiled forms of the Standard Version without
132% the Source, provided that you include complete instructions on how to
133% get the Source of the Standard Version. Such instructions must be
134% valid at the time of your distribution. If these instructions, at any
135% time while you are carrying out such distribution, become invalid, you
136% must provide new instructions on demand or cease further
137% distribution. If you provide valid instructions or cease distribution
138% within thirty days after you become aware that the instructions are
139% invalid, then you do not forfeit any of your rights under this
140% license.
141%
142% (6) You may Distribute a Modified Version in Compiled form without the
143% Source, provided that you comply with Section 4 with respect to the
144% Source of the Modified Version.
145%
146% Aggregating or Linking the Package
147%
148% (7) You may aggregate the Package (either the Standard Version or
149% Modified Version) with other packages and Distribute the resulting
150% aggregation provided that you do not charge a licensing fee for the
151% Package. Distributor Fees are permitted, and licensing fees for other
152% components in the aggregation are permitted. The terms of this license
153% apply to the use and Distribution of the Standard or Modified Versions
154% as included in the aggregation.
155%
156% (8) You are permitted to link Modified and Standard Versions with
157% other works, to embed the Package in a larger work of your own, or to
158% build stand-alone binary or bytecode versions of applications that
159% include the Package, and Distribute the result without restriction,
160% provided the result does not expose a direct interface to the Package.
161%
162% Items That are Not Considered Part of a Modified Version
163%
164% (9) Works (including, but not limited to, modules and scripts) that
165% merely extend or make use of the Package, do not, by themselves, cause
166% the Package to be a Modified Version. In addition, such works are not
167% considered parts of the Package itself, and are not subject to the
168% terms of this license.
169%
170% General Provisions
171%
172% (10) Any use, modification, and distribution of the Standard or
173% Modified Versions is governed by this Artistic License. By using,
174% modifying or distributing the Package, you accept this license. Do not
175% use, modify, or distribute the Package, if you do not accept this
176% license.
177%
178% (11) If your Modified Version has been derived from a Modified Version
179% made by someone other than you, you are nevertheless required to
180% ensure that your Modified Version complies with the requirements of
181% this license.
182%
183% (12) This license does not grant you the right to use any trademark,
184% service mark, tradename, or logo of the Copyright Holder.
185%
186% (13) This license includes the non-exclusive, worldwide,
187% free-of-charge patent license to make, have made, use, offer to sell,
188% sell, import and otherwise transfer the Package with respect to any
189% patent claims licensable by the Copyright Holder that are necessarily
190% infringed by the Package. If you institute patent litigation
191% (including a cross-claim or counterclaim) against any party alleging
192% that the Package constitutes direct or contributory patent
193% infringement, then this Artistic License to you shall terminate on the
194% date that such litigation is filed.
195%
196% (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT
197% HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED
198% WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
199% PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT
200% PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT
201% HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT,
202% INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE
203% OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
204%
205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
206
207:- module(mc_DNF_sampling, [problog_dnf_sampling/3]).
208
209:- use_module(library(lists), [memberchk/2]).
210
211:- use_module(variables).
212:- use_module(sampling, _, [problog_random/1,
213                            problog_convergence_check/6]).
214
215:- use_module(flags, _, [problog_define_flag/5,
216                         problog_flag/2]).
217
218:- use_module(os, _, [convert_filename_to_working_path/2]).
219
220:- use_module(hash_table).
221
222:- initialization((
223  problog_define_flag(search_method, problog_flag_validate_in_list([linear, binary]), 'search method for picking proof', binary, monte_carlo_sampling_dnf),
224  problog_define_flag(represent_world, problog_flag_validate_in_list([list, record, array, hash_table]), 'structure that represents sampled world', array, monte_carlo_sampling_dnf),
225
226  problog_var_define(dnf_sampling_time, times, time, messages('DNF Sampling', ':', ' ms')),
227  problog_var_define(probability_lower, result, untyped, messages('Lower probability bound', ' = ', '')),
228  problog_var_define(probability_upper, result, untyped, messages('Upper probability bound', ' = ', ''))
229)).
230
231% problog_independed(T, P):-
232%   tries:trie_traverse_first(T, FirstRef), !,
233%   problog_independed(FirstRef, P, 0.0, _, 0).
234% problog_independed(_T, 0.0).
235
236problog_independed(T, P, ProofCNT):-
237  tries:trie_traverse_first(T, FirstRef), !,
238  problog_independed(FirstRef, P, 0.0, ProofCNT, 0).
239problog_independed(_T, 0.0, 0).
240
241%%% this should be generalized to handle nested tries
242problog_independed([], P, P, ProofCNT, ProofCNT).
243problog_independed(ProofRef, P, A, ProofCNT, Index):-
244  tries:trie_get_entry(ProofRef, Proof),
245  calculate_prob_proof(Proof, Pproof),
246  calculate_prob_proof(Proof, Pproof),
247  NA is A + Pproof,
248  NIndex is Index + 1,
249  recordz(problog_mc_dnf, proof(Index, ProofRef, Pproof, NA), _),
250  (tries:trie_traverse_next(ProofRef, NxtProofRef) ->
251    NextProofRef = NxtProofRef
252  ;
253    NextProofRef = []
254  ),
255  problog_independed(NextProofRef, P, NA, ProofCNT, NIndex).
256
257
258%%% this should be generalized to handle nested tries
259calculate_prob_proof([true], 1.0):-!.
260calculate_prob_proof(Proof, P):-
261  calculate_curr_prob(Proof, 0.0, L),
262  P is exp(L).
263
264
265calculate_curr_prob([], Acc, Acc).
266calculate_curr_prob([ID|Rest], AccCurrProb, CurrProb):-
267  get_log_prob_not_check(ID, IDProb),
268  AccCurrProb1 is AccCurrProb + IDProb,
269  calculate_curr_prob(Rest, AccCurrProb1, CurrProb).
270
271%%%% this should be generalized and go to problog_fact module
272get_log_prob_not_check(not(ID), IDProb):-
273  !, problog:get_fact_probability(ID, Prob1),
274  Prob2 is 1 - Prob1, IDProb is log(Prob2).
275get_log_prob_not_check(ID, IDProb):-
276  problog:get_fact_log_probability(ID, IDProb).
277
278
279problog_mc_DNF(Trie, Delta, P):-
280  problog_flag(mc_batchsize, Samples),
281  problog_independed(Trie, Pind, ProofCNT),
282  (ProofCNT > 1 ->
283    problog_mc_DNF(Trie, Pind, ProofCNT, Delta, Samples, 0, SamplesSoFar, Naccepted, 0, _Epsilon),
284    P is Naccepted / SamplesSoFar * Pind
285  ;
286    P is Pind,
287    problog_var_set(probability, P)
288  ),
289  eraseall(problog_mc_dnf).
290
291problog_mc_DNF(_Trie, Pind, _ProofCNT, Delta, Samples, SamplesSoFar, SamplesSoFar, Naccepted, Naccepted, Epsilon):-
292  SamplesSoFar > 0,
293  SamplesSoFar mod Samples =:= 0,
294  P is Naccepted / SamplesSoFar * Pind,
295  problog_timer_pause(dnf_sampling_time, T),
296  problog_timer_resume(dnf_sampling_time),
297  problog_convergence_check(T, P, SamplesSoFar, Delta, Epsilon, Converge),
298  (Converge = true; Converge = terminate), !,
299  problog_var_set(samples, SamplesSoFar),
300  problog_var_set(probability, P),
301  Pl is P - Epsilon,
302  Ph is P + Epsilon,
303  problog_var_set(probability_lower, Pl),
304  problog_var_set(probability_upper, Ph).
305/*
306problog_mc_DNF(_Trie, _Pind, _ProofCNT, _Delta, Samples, SamplesSoFar, _SamplesSoFar, _Naccepted, _Naccepted, _Epsilon):-
307  SamplesSoFar mod Samples =:= 0,
308  fail.*/
309
310problog_mc_DNF(Trie, Pind, ProofCNT, Delta, Samples, SAcc, SamplesSoFar, Naccepted, NAcc, Epsilon):-
311  NSAcc is SAcc + 1,
312  problog_random(RND),
313  Thr is RND * Pind,
314  tries:trie_traverse_mode(backward),
315  (problog_flag(search_method, binary) ->
316    get_sample_proof_binary(CurRef, Thr, ProofCNT, L_true_pf, L_false_pf)
317  ;
318    get_sample_proof_linear(CurRef, Thr, L_true_pf, L_false_pf)
319  ),
320  (tries:trie_traverse_next(CurRef, NxtRef) ->
321    NextRef = NxtRef
322  ;
323    NextRef = []
324  ),
325  (check_sample_proofs(NextRef, L_true_pf, L_false_pf) ->
326    NNAcc is NAcc + 1
327  ;
328    NNAcc is NAcc
329  ),
330  (problog_flag(represent_world, record) ->
331    eraseall(problog_sample_world)
332  ;
333    (problog_flag(represent_world, array) ->
334      close_static_array(problog_sample_world)
335    ;
336      (problog_flag(represent_world, hash_table) ->
337        hash_table_delete(L_true_pf),
338        hash_table_delete(L_false_pf)
339      ;
340        true
341      )
342    )
343  ),
344  tries:trie_traverse_mode(forward),
345  problog_mc_DNF(Trie, Pind, ProofCNT, Delta, Samples, NSAcc, SamplesSoFar, Naccepted, NNAcc, Epsilon).
346
347
348get_sample_proof_linear(Ref, Thr, L_true_pf, L_false_pf):-
349  recorded(problog_mc_dnf, proof(_Index, Ref, _Pproof, Ps), _),
350  Thr < Ps,
351  tries:trie_get_entry(Ref, Proof),
352  (problog_flag(represent_world, hash_table) ->
353    make_hash_tables(L_true_pf, L_false_pf),
354    add_proof_to_hash_world(Proof, L_true_pf, L_false_pf)
355  ;
356    (problog_flag(represent_world, record) ->
357      add_proof_to_rec_world(Proof)
358    ;
359      (problog_flag(represent_world, array) ->
360        nb_getval(probclause_counter, ProbFactCNT),
361        Size is ProbFactCNT + 1,
362        static_array(problog_sample_world, Size, int),
363        add_proof_to_array_world(Proof)
364      ;
365        add_proof_to_list_world(Proof, L_true_pf, L_false_pf)
366      )
367    )
368  ).
369
370get_sample_proof_binary(Ref, Thr, ProofCNT, L_true_pf, L_false_pf):-
371  Last is ProofCNT - 1,
372  binary_search(Thr, 0, Last, Ref), !,
373  tries:trie_get_entry(Ref, Proof),
374  (problog_flag(represent_world, hash_table) ->
375    make_hash_tables(L_true_pf, L_false_pf),
376    add_proof_to_hash_world(Proof, L_true_pf, L_false_pf)
377  ;
378    (problog_flag(represent_world, record) ->
379      add_proof_to_rec_world(Proof)
380    ;
381      (problog_flag(represent_world, array) ->
382        nb_getval(probclause_counter, ProbFactCNT),
383        Size is ProbFactCNT + 1,
384        static_array(problog_sample_world, Size, int),
385        add_proof_to_array_world(Proof)
386      ;
387        add_proof_to_list_world(Proof, L_true_pf, L_false_pf)
388      )
389    )
390  ).
391
392
393binary_search(Thr, From, To, Ref):-
394  1 is To - From, !,
395  recorded(problog_mc_dnf, proof(From, RefF, _Pproof, PsF), _),
396  (Thr > PsF ->
397    recorded(problog_mc_dnf, proof(To, Ref, _PproofTo, _Ps), _)
398  ;
399    Ref = RefF
400  ).
401
402binary_search(_Thr, Index, Index, Ref):-
403  !, recorded(problog_mc_dnf, proof(Index, Ref, _Pproof, _Ps), _).
404
405binary_search(Thr, From, To, Res):-
406  Look is From + integer((To - From + 1) / 2),
407  recorded(problog_mc_dnf, proof(Look, _Ref, _Pproof, Ps), _), !,
408  (Thr > Ps ->
409    NewFrom is Look + 1,
410    NewTo is To
411  ;
412    NewFrom is From,
413    NewTo is Look
414  ),
415  binary_search(Thr, NewFrom, NewTo, Res).
416
417
418%%%%%%%%% This code can be improved and generalized %%%%%%%%%
419check_sample_proofs([], _, _).
420
421check_sample_proofs(CurRef, L_true_pf, L_false_pf):-
422  !, tries:trie_get_entry(CurRef, Proof),
423  (problog_flag(represent_world, hash_table) ->
424    check_proof_in_hash_world(Proof, L_true_pf, L_false_pf),
425    NL_true_pf = L_true_pf,
426    NL_false_pf = L_false_pf
427  ;
428    (problog_flag(represent_world, record) ->
429      check_proof_in_rec_world(Proof),
430      NL_true_pf = L_true_pf,
431      NL_false_pf = L_false_pf
432    ;
433      (problog_flag(represent_world, array) ->
434        check_proof_in_array_world(Proof),
435        NL_true_pf = L_true_pf,
436        NL_false_pf = L_false_pf
437      ;
438        check_proof_in_list_world(Proof, L_true_pf, NL_true_pf, L_false_pf, NL_false_pf)
439      )
440    )
441  ),
442  (tries:trie_traverse_next(CurRef, NxtRef) ->
443    NextRef = NxtRef
444  ;
445    NextRef = []
446  ),
447  check_sample_proofs(NextRef, NL_true_pf, NL_false_pf).
448
449add_proof_to_array_world([]).
450add_proof_to_array_world([not(H)|T]):-
451  !, update_array(problog_sample_world, H, -1), add_proof_to_array_world(T).
452add_proof_to_array_world([H|T]):-
453  update_array(problog_sample_world, H, 1), add_proof_to_array_world(T).
454
455
456check_proof_in_array_world([not(F)|_Rest]):-
457  array_element(problog_sample_world, F, 1), !.
458
459check_proof_in_array_world([not(F)|Rest]):-
460  array_element(problog_sample_world, F, -1), !,
461  check_proof_in_array_world(Rest).
462
463check_proof_in_array_world([not(F)|Rest]):-
464  !, problog_random(RND), Dice is RND,
465  problog:get_fact_probability(F, NumProbF),
466  (Dice =< NumProbF ->
467    update_array(problog_sample_world, F, 1)
468  ;
469    update_array(problog_sample_world, F, -1),
470    check_proof_in_array_world(Rest)
471  ).
472
473check_proof_in_array_world([F|_Rest]):-
474  array_element(problog_sample_world, F, -1), !.
475
476check_proof_in_array_world([F|Rest]):-
477  array_element(problog_sample_world, F, 1), !,
478  check_proof_in_array_world(Rest).
479
480check_proof_in_array_world([F|Rest]):-
481  !, problog_random(RND), Dice is RND,
482  problog:get_fact_probability(F, NumProbF),
483  (Dice > NumProbF ->
484    update_array(problog_sample_world, F, -1)
485  ;
486    update_array(problog_sample_world, F, 1),
487    check_proof_in_array_world(Rest)
488  ).
489
490
491
492
493add_proof_to_rec_world([]).
494add_proof_to_rec_world([not(H)|T]):-
495  !, recordz(problog_sample_world, false_fact(H), _), add_proof_to_rec_world(T).
496add_proof_to_rec_world([H|T]):-
497  recordz(problog_sample_world, true_fact(H), _), add_proof_to_rec_world(T).
498
499check_proof_in_rec_world([not(F)|_Rest]):-
500  recorded(problog_sample_world, true_fact(F), _), !.
501
502check_proof_in_rec_world([not(F)|Rest]):-
503  recorded(problog_sample_world, false_fact(F), _), !,
504  check_proof_in_rec_world(Rest).
505
506check_proof_in_rec_world([not(F)|Rest]):-
507  !, problog_random(RND), Dice is RND,
508  problog:get_fact_probability(F, NumProbF),
509  (Dice =< NumProbF ->
510    recordz(problog_sample_world, true_fact(F), _)
511  ;
512    recordz(problog_sample_world, false_fact(F), _),
513    check_proof_in_rec_world(Rest)
514  ).
515
516check_proof_in_rec_world([F|_Rest]):-
517  recorded(problog_sample_world, false_fact(F), _), !.
518
519check_proof_in_rec_world([F|Rest]):-
520  recorded(problog_sample_world, true_fact(F), _), !,
521  check_proof_in_rec_world(Rest).
522
523check_proof_in_rec_world([F|Rest]):-
524  !, problog_random(RND), Dice is RND,
525  problog:get_fact_probability(F, NumProbF),
526  (Dice > NumProbF ->
527    recordz(problog_sample_world, false_fact(F), _)
528  ;
529    recordz(problog_sample_world, true_fact(F), _),
530    check_proof_in_rec_world(Rest)
531  ).
532
533
534
535make_hash_tables(TrueHashTable, FalseHashTable):-
536  nb_getval(probclause_counter, ProbFactCNT),
537  hash_table_init(ProbFactCNT, TrueHashTable),
538  hash_table_init(ProbFactCNT, FalseHashTable).
539
540
541add_proof_to_hash_world([], _TrueHashTable, _FalseHashTable).
542add_proof_to_hash_world([not(H)|T], TrueHashTable, FalseHashTable):-
543  !, problog_key_to_tuple(H, Tuple),
544  hash_table_lookup(FalseHashTable, Tuple, _),
545  add_proof_to_hash_world(T, TrueHashTable, FalseHashTable).
546add_proof_to_hash_world([H|T], TrueHashTable, FalseHashTable):-
547  problog_key_to_tuple(H, Tuple),
548  hash_table_lookup(TrueHashTable, Tuple, _),
549  add_proof_to_hash_world(T, TrueHashTable, FalseHashTable).
550
551
552check_proof_in_hash_world([not(F)|_Rest], TrueHashTable, _FalseHashTable):-
553  problog_key_to_tuple(F, Tuple),
554  hash_table_contains(TrueHashTable, Tuple, _), !.
555
556check_proof_in_hash_world([not(F)|Rest], TrueHashTable, FalseHashTable):-
557  problog_key_to_tuple(F, Tuple),
558  hash_table_contains(FalseHashTable, Tuple, _), !,
559  check_proof_in_hash_world(Rest, TrueHashTable, FalseHashTable).
560
561check_proof_in_hash_world([not(F)|Rest], TrueHashTable, FalseHashTable):-
562  !, problog_random(RND), Dice is RND,
563  problog:get_fact_probability(F, NumProbF),
564  problog_key_to_tuple(F, Tuple),
565  (Dice =< NumProbF ->
566    hash_table_lookup(TrueHashTable, Tuple, _)
567  ;
568    hash_table_lookup(FalseHashTable, Tuple, _),
569    check_proof_in_hash_world(Rest, TrueHashTable, FalseHashTable)
570  ).
571
572check_proof_in_hash_world([F|_Rest], _TrueHashTable, FalseHashTable):-
573  problog_key_to_tuple(F, Tuple),
574  hash_table_contains(FalseHashTable, Tuple, _), !.
575
576check_proof_in_hash_world([F|Rest], TrueHashTable, FalseHashTable):-
577  problog_key_to_tuple(F, Tuple),
578  hash_table_contains(TrueHashTable, Tuple, _), !,
579  check_proof_in_hash_world(Rest, TrueHashTable, FalseHashTable).
580
581check_proof_in_hash_world([F|Rest], TrueHashTable, FalseHashTable):-
582  !, problog_random(RND), Dice is RND,
583  problog:get_fact_probability(F, NumProbF),
584  problog_key_to_tuple(F, Tuple),
585  (Dice > NumProbF ->
586    hash_table_lookup(FalseHashTable, Tuple, _)
587  ;
588    hash_table_lookup(TrueHashTable, Tuple, _),
589    check_proof_in_hash_world(Rest, TrueHashTable, FalseHashTable)
590  ).
591
592
593
594add_proof_to_list_world([], [], []).
595add_proof_to_list_world([not(H)|T], TrueList, [H|FalseList]):-
596  add_proof_to_list_world(T, TrueList, FalseList).
597add_proof_to_list_world([H|T], [H|TrueList], FalseList):-
598  add_proof_to_list_world(T, TrueList, FalseList).
599
600check_proof_in_list_world([not(F)|_Rest], TrueList, TrueList, FalseList, FalseList):-
601  memberchk(F, TrueList), !.
602
603check_proof_in_list_world([not(F)|Rest], TrueList, NewTrueList, FalseList, NewFalseList):-
604  memberchk(F, FalseList), !,
605  check_proof_in_list_world(Rest, TrueList, NewTrueList, FalseList, NewFalseList).
606
607check_proof_in_list_world([not(F)|Rest], TrueList, NewTrueList, FalseList, NewFalseList):-
608  !, problog_random(RND), Dice is RND,
609  problog:get_fact_probability(F, NumProbF),
610  (Dice =< NumProbF ->
611    NewTrueList = [F|TrueList],
612    NewFalseList = FalseList
613  ;
614    check_proof_in_list_world(Rest, TrueList, NewTrueList, [F|FalseList], NewFalseList)
615  ).
616
617check_proof_in_list_world([F|_Rest], TrueList, TrueList, FalseList, FalseList):-
618  memberchk(F, FalseList), !.
619
620check_proof_in_list_world([F|Rest], TrueList, NewTrueList, FalseList, NewFalseList):-
621  memberchk(F, TrueList), !,
622  check_proof_in_list_world(Rest, TrueList, NewTrueList, FalseList, NewFalseList).
623
624check_proof_in_list_world([F|Rest], TrueList, NewTrueList, FalseList, NewFalseList):-
625  !, problog_random(RND), Dice is RND,
626  problog:get_fact_probability(F, NumProbF),
627  (Dice > NumProbF ->
628    NewTrueList = TrueList,
629    NewFalseList = [F|FalseList]
630  ;
631    check_proof_in_list_world(Rest, [F|TrueList], NewTrueList, FalseList, NewFalseList)
632  ).
633
634
635
636problog_collect_trie(Goal, Threshold) :-
637  problog:init_problog_low(Threshold),
638  problog:problog_control(off, up),
639  problog:problog_control(on, exact),
640  problog_var_timer_start(sld_time),
641  problog:problog_call(Goal),
642  problog:add_solution,
643  fail.
644problog_collect_trie(_, _) :-
645  problog:problog_control(off, exact),
646  problog_var_timer_stop(sld_time).
647
648problog_dnf_sampling(Goal, Delta, P):-
649  % this should be generalized with general log file
650  problog_flag(mc_logfile, File1),
651  convert_filename_to_working_path(File1, File),
652  open(File, write, Log),
653  format(Log,'# goal: ~q~n#delta: ~w~n',[Goal, Delta]),
654  format(Log,'# samples  prob   low   high  time~2n',[]),
655  close(Log),
656
657  problog_collect_trie(Goal, 0.0),
658  nb_getval(problog_completed_proofs, Trie_Completed_Proofs),
659  problog_var_timer_start(dnf_sampling_time),
660  problog_mc_DNF(Trie_Completed_Proofs, Delta, P),
661  problog_var_timer_stop(dnf_sampling_time),
662  (problog_flag(verbose, true) ->
663    print:problog_statistics
664  ;
665    true
666  ),
667  ptree:delete_ptree(Trie_Completed_Proofs),
668  problog:clear_tabling.
669