1
+ use std:: num:: NonZero ;
2
+
1
3
use super :: ConflictResolver ;
2
4
use crate :: basic_types:: moving_averages:: MovingAverage ;
5
+ use crate :: basic_types:: HashMap ;
3
6
use crate :: basic_types:: PredicateId ;
4
7
use crate :: basic_types:: PredicateIdGenerator ;
5
8
use crate :: branching:: Brancher ;
@@ -12,6 +15,7 @@ use crate::engine::conflict_analysis::LearnedNogood;
12
15
use crate :: engine:: propagation:: CurrentNogood ;
13
16
use crate :: engine:: Assignments ;
14
17
use crate :: predicates:: Predicate ;
18
+ use crate :: proof:: ProofLog ;
15
19
use crate :: pumpkin_assert_advanced;
16
20
use crate :: pumpkin_assert_moderate;
17
21
use crate :: pumpkin_assert_simple;
@@ -75,6 +79,8 @@ impl ConflictResolver for ResolutionResolver {
75
79
self . add_predicate_to_conflict_nogood (
76
80
* predicate,
77
81
context. assignments ,
82
+ context. proof_log ,
83
+ context. unit_nogood_step_ids ,
78
84
context. brancher ,
79
85
self . mode ,
80
86
context. is_completing_proof ,
@@ -244,6 +250,8 @@ impl ConflictResolver for ResolutionResolver {
244
250
self . add_predicate_to_conflict_nogood (
245
251
* predicate,
246
252
context. assignments ,
253
+ context. proof_log ,
254
+ context. unit_nogood_step_ids ,
247
255
context. brancher ,
248
256
self . mode ,
249
257
context. is_completing_proof ,
@@ -273,13 +281,19 @@ impl ResolutionResolver {
273
281
self . to_process_heap . clear ( ) ;
274
282
}
275
283
284
+ #[ allow(
285
+ clippy:: too_many_arguments,
286
+ reason = "borrow checker complains if passing through the context"
287
+ ) ]
276
288
fn add_predicate_to_conflict_nogood (
277
289
& mut self ,
278
290
predicate : Predicate ,
279
291
assignments : & Assignments ,
292
+ proof_log : & mut ProofLog ,
293
+ unit_nogood_step_ids : & HashMap < Predicate , NonZero < u64 > > ,
280
294
brancher : & mut dyn Brancher ,
281
295
mode : AnalysisMode ,
282
- is_logging_complete_proof : bool ,
296
+ is_completing_proof : bool ,
283
297
) {
284
298
let dec_level = assignments
285
299
. get_decision_level_for_predicate ( & predicate)
@@ -290,18 +304,34 @@ impl ResolutionResolver {
290
304
assignments. get_upper_bound( predicate. get_domain( ) ) ,
291
305
)
292
306
} ) ;
293
- // Ignore root level predicates.
294
- if !is_logging_complete_proof && dec_level == 0 {
295
- // do nothing
307
+
308
+ // Log all non-initial bounds to the proof.
309
+ if dec_level == 0 && !is_completing_proof {
310
+ if !assignments. is_initial_bound ( predicate) {
311
+ let trail_index = assignments
312
+ . get_trail_position ( & predicate)
313
+ . expect ( "all predicates in reason are true" ) ;
314
+ let trail_entry = assignments. get_trail_entry ( trail_index) ;
315
+
316
+ // We do indicate their usage in the proof.
317
+ let step_id = unit_nogood_step_ids
318
+ . get ( & trail_entry. predicate )
319
+ . copied ( )
320
+ . unwrap ( ) ;
321
+ proof_log. add_propagation ( step_id) ;
322
+ }
323
+
324
+ return ;
296
325
}
326
+
297
327
// 1UIP
298
328
// If the variables are from the current decision level then we want to potentially add
299
329
// them to the heap, otherwise we add it to the predicates from lower-decision levels
300
330
//
301
331
// All-decision Learning
302
332
// If the variables are not decisions then we want to potentially add them to the heap,
303
333
// otherwise we add it to the decision predicates which have been discovered previously
304
- else if match mode {
334
+ if match mode {
305
335
AnalysisMode :: OneUIP => dec_level == assignments. get_decision_level ( ) ,
306
336
AnalysisMode :: AllDecision => !assignments. is_decision_predicate ( & predicate) ,
307
337
} {
0 commit comments