ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
congruence.hpp
Go to the documentation of this file.
1#ifndef _congruenc_hpp_INCLUDED
2#define _congruenc_hpp_INCLUDED
3
4#include "global.h"
5
6#include <algorithm>
7#include <array>
8#include <cassert>
9#include <cstddef>
10#include <cstdint>
11#include <queue>
12#include <string>
13#include <sys/types.h>
14#include <unordered_set>
15#include <vector>
16
17#include "clause.hpp"
18#include "inttypes.hpp"
19#include "util.hpp"
20#include "watch.hpp"
21
23
24namespace CaDiCaL {
25
26typedef int64_t LRAT_ID;
27
28// This implements the algorithm algorithm from SAT 2024.
29//
30// The idea is to:
31// 0. handle binary clauses
32// 1. detect gates and merge gates with same inputs ('lazy')
33// 2. eagerly replace the equivalent literals and merge gates with same
34// inputs
35// 3. forward subsume
36//
37// In step 0 the normalization is fully lazy but we do not care about a
38// normal form. Therefore we actually eagerly merge literals.
39//
40// In step 2 there is a subtility: we only replace with the equivalence
41// chain as far as we propagated so far. This is the eager part. For LRAT we
42// produce the equivalence up to the point we have propagated, no the full
43// chain. This is important for merging literals. To merge literals we use
44// union-find but we only compress paths when rewriting the literal, not
45// before. The compression was not considered important in Kissat, but we do
46// it aggressively as a mirror of the equivalences we have generated.
47//
48// We have two structures for merging:
49// - the lazy ones contains alls merges, with functions like
50// find_representative
51//
52// - the eager version that gets the merges one by one, with functions
53// like find_eager_representatives
54//
55// The two structures are nicely separated and we only working on one of
56// them except for:
57//
58// 1. When propagating one equivalence, we first important the
59// equivalence from the lazy to the eager version, producing the full
60// chain.
61//
62// 2. When merging the literals, we merge the literals given by the lazy
63// structure, then we merge their representative in the eager version,
64// updating only the lazy structure. We do not update the eager version.
65//
66// An important point: We cannot use internal->lrat_chain and
67// internal->clause because in most places we can interrupt the
68// transformation to learn a new clause representing an equivalence.
69// However, we can only have 2 layers so we use this->lrat_chain and
70// internal->lrat_chain when we really produce the proof.
71struct Internal;
72
73#define LD_MAX_ARITY 26
74#define MAX_ARITY ((1 << LD_MAX_ARITY) - 1)
75
77
78// Wrapper when we are looking for implication in if-then-else gates
80 int first;
81 int second;
83 lit_implication (int f, int s, Clause *_id)
84 : first (f), second (s), clause (_id) {}
85 lit_implication (int f, int s) : first (f), second (s), clause (0) {}
86 lit_implication () : first (0), second (0), clause (nullptr) {}
87 void swap () { std::swap (first, second); }
88};
89
90// Wrapper when we are looking for equivalence for if-then-else-gate. They
91// are produced by merging implication
93 int first;
94 int second;
100 CADICAL_assert (std::find (begin (*first_clause), end (*first_clause), first) !=
101 end (*first_clause));
102 CADICAL_assert (std::find (begin (*second_clause), end (*second_clause),
103 second) != end (*second_clause));
104 CADICAL_assert (std::find (begin (*first_clause), end (*first_clause),
105 -second) != end (*first_clause));
106 CADICAL_assert (std::find (begin (*second_clause), end (*second_clause),
107 -first) != end (*second_clause));
108 }
109 lit_equivalence (int f, Clause *f_id, int s, Clause *s_id)
110 : first (f), second (s), first_clause (f_id), second_clause (s_id) {}
111 lit_equivalence (int f, int s)
112 : first (f), second (s), first_clause (nullptr),
113 second_clause (nullptr) {}
115 : first (0), second (0), first_clause (nullptr),
116 second_clause (nullptr) {}
118 std::swap (first, second);
119 std::swap (first_clause, second_clause);
120 return *this;
121 }
123 first = -first;
124 second = -second;
125 std::swap (first_clause, second_clause);
126 return *this;
127 }
128};
129
130typedef std::vector<lit_implication> lit_implications;
131typedef std::vector<lit_equivalence> lit_equivalences;
132
133std::string string_of_gate (Gate_Type t);
134
136 int current_lit; // current literal from the gate
139 LitClausePair () : current_lit (0), clause (nullptr) {}
140};
141struct LitIdPair {
142 int lit; // current literal from the gate
144 LitIdPair (int l, LRAT_ID i) : lit (l), id (i) {}
145 LitIdPair () : lit (0), id (0) {}
146};
147
148/*------------------------------------------------------------------------*/
149
150// Sorting the scheduled clauses is way faster if we compute and save the
151// clause size in the schedule to avoid pointer access to clauses during
152// sorting. This slightly increases the schedule size though.
153
155 size_t size;
157 ClauseSize (int s, Clause *c) : size (s), clause (c) {}
158 ClauseSize (Clause *c): size (c->size), clause (c) {}
160};
161
163 typedef size_t Type;
164 Type operator() (const ClauseSize &a) { return a.size; }
165};
166
167/*------------------------------------------------------------------------*/
168// There are many special cases for ITE gates and we have to keep track of
169// them as it is a gate property (rewriting might not make it obvious
170// anymore).
171// a = (a ? t : e) results in no -t and no +e gate (a --> a = t == (-a v -a v t) & (-a v a v -t))
172// a = (-a ? t : e) results in no +t and no -e gate
173// a = (c ? a : e) results in no t gate (none of them)
174// a = (c ? t : a) results in no e gate (none of them)
175
187
188inline bool ite_flags_no_then_clauses (int8_t flag) {
189 return (flag & NO_THEN) == NO_THEN;
190}
191
192inline bool ite_flags_no_else_clauses (int8_t flag) {
193 return (flag & NO_ELSE) == NO_ELSE;
194}
195
196inline bool ite_flags_neg_cond_lhs (int8_t flag) {
197 return (flag & UCOND_LHS) == UCOND_LHS;
198}
199
200inline bool ite_flags_cond_lhs (int8_t flag) {
201 return (flag & COND_LHS) == COND_LHS;
202}
203
204/*------------------------------------------------------------------------*/
205
206// The core structure of this algorithm: the gate. It is composed of a
207// left-hand side and an array of right-hand side.
208//
209// There are a few tags to help remembering the status of the gate (like
210// deleted)
211//
212// To keep track of the proof we use two extra arrays:
213// - `neg_lhs_ids' contains the long clause for AND gates. Otherwise, it is
214// empty. TODO: change to std::option as it contains at most one element
215// - `pos_lhs_ids' contains all the remaining gates.
216//
217// We keep the reasons with an index. This index depends on the gates:
218
219// - AND-Gates and ITE-Gates: the index is the literal from the RHS
220//
221// - XOR-Gates: if you order the clauses by the order of the literals,
222// each literal is either positive (bit '1') or negative (bit '0'). This
223// gives a number that we can use.
224//
225// TODO Florian: I do not think that you have to changed anything, look at
226// the 'Look at this first' in the CPP file.
227//
228// Important for the proofs: the LHS is not updated.
229//
230// TODO: we currently use a vector for the rhs, but we could also use FMA
231// and inline the structure to avoid any indirection.
232//
233// One warning for degenerated gate: it is a monotone property on the
234// defining clauses, but not on the LHS/RHS as the LHS is not rewritten:
235// take 4 = AND 3 4 (degenerated with only the clause -4 3) with a rewriting
236// 4 -> 1 (unchanged clause) and later 1 -> 3 (unchanged clause) but you do
237// not know anymore from the gate that it is degenerated
238struct Gate {
239#ifdef LOGGING
240 uint64_t id;
241#endif
242 int lhs;
244 bool garbage : 1;
245 bool indexed : 1;
246 bool marked : 1;
247 bool shrunken : 1;
248 size_t hash; // TODO remove this field (the C++ implementation is caching
249 // it anyway)
252 bool degenerated_and_neg = false; // LRAT only relevant for AND Gates, neg lhs in RHS
253 bool degenerated_and_pos = false; // LRAT only relevant for AND Gates, pos lhs in RHS
256
257 size_t arity () const { return rhs.size (); }
258
259 bool operator== (Gate const &lhs) {
260 return tag == lhs.tag && hash == lhs.hash && rhs == lhs.rhs;
261 }
262};
263
265
267 bool operator() (const Gate *const lhs, const Gate *const rhs) const {
268 return lhs->rhs == rhs->rhs && lhs->tag == rhs->tag;
269 }
270};
271
275 int lit1, lit2;
276 CompactBinary (Clause *c, LRAT_ID i, int l1, int l2)
277 : clause (c), id (i), lit1 (l1), lit2 (l2) {}
278 CompactBinary () : clause (nullptr), id (0), lit1 (0), lit2 (0) {}
279};
280
281struct Hash {
282 Hash (std::array<int, 16> &ncs) : nonces (ncs) {}
283 std::array<int, 16> &nonces;
284 size_t operator() (const Gate *const g) const;
285};
286
287struct Rewrite {
288 int src, dst;
291
292 Rewrite (int _src, int _dst, LRAT_ID _id1, LRAT_ID _id2)
293 : src (_src), dst (_dst), id1 (_id1), id2 (_id2) {}
294 Rewrite () : src (0), dst (0), id1 (0), id2 (0) {}
295};
296
297struct Closure {
298
299 Closure (Internal *i);
300
304 std::vector<std::pair<size_t, size_t>> offsetsize;
305 bool full_watching = false;
306 std::array<int, 16> nonces;
307 typedef unordered_set<Gate *, Hash, GateEqualTo> GatesTable;
308
312 mu4_ids; // remember the ids and the literal. 2 and 4 are
313 // only used for lrat proofs, but we need 1 to
314 // promote binary clauses to irredundant
315
316 vector<int> lits; // result of definitions
317 vector<int> rhs; // stack for storing RHS
318 vector<int> unsimplified; // stack for storing unsimplified version (XOR,
319 // ITEs) for DRAT proof
320 vector<int> chain; // store clauses to be able to delete them properly
321 vector<int> clause; // storing partial clauses
323 glargecounts; // count for large clauses to complement internal->noccs
324 vector<uint64_t> gnew_largecounts; // count for large clauses to
325 // complement internal->noccs
327 std::array<lit_implications, 2> condbin;
328 std::array<lit_equivalences, 2> condeq;
329
330 std::vector<Clause *> new_unwatched_binary_clauses;
331 // LRAT proofs
333 mutable vector<LRAT_ID> lrat_chain; // storing LRAT chain
334
335#ifdef LOGGING
336 uint64_t fresh_id;
337#endif
338
339 uint64_t &new_largecounts (int lit);
340 uint64_t &largecounts (int lit);
341
342 void unmark_all ();
345 vector<LRAT_ID> representant_id; // lrat version of union-find
346 vector<LRAT_ID> eager_representant_id; // lrat version of union-find
347 int &representative (int lit);
348 int representative (int lit) const;
350 LRAT_ID representative_id (int lit) const;
351 int &eager_representative (int lit);
352 int eager_representative (int lit) const;
355 std::vector<char> lazy_propagated_idx;
356 char &lazy_propagated (int lit);
357
359 // representative in the union-find structure in the lazy equivalences
360 int find_representative (int lit);
361 // find the representative and produce the binary clause representing the
362 // normalization from the literal to the result.
363 int find_representative_and_compress (int, bool update_eager = true);
364 // find the lazy representative for the `lit' and `-lit'
366 // find the eager representative
368
369 // compreses the path from lit to the representative with a new clause if
370 // needed. Save internal->lrat_chain to avoid any issue.
372 // Import the path from the literal and its negation to the representative
373 // in the lazy graph to the eager part, producing the binary clauses.
375 int); // generates clauses for -lit and lit
376
377 // returns the ID of the LRAT clause for the normalization from the
378 // literal lit to its argument, assuming that the representative was
379 // already compressed.
381 // returns the ID of the LRAT clause for the eager normalization from the
382 // literal lit to its argument assuming that the representative was
383 // already compressed.
385
386 // Writes the LRAT chain required for the eager normalization to
387 // `lrat_chain`.
389 // Writes the LRAT chain required for the lazy normalization to
390 // `lrat_chain`.
392
393 // learns a binary clause if not unit
394 Clause *maybe_add_binary_clause (int a, int b);
395 // add binary clause
396 Clause *add_binary_clause (int a, int b);
397 // add tmp clause
398 Clause *add_tmp_binary_clause (int a, int b);
399 // add clause taking core of tmp or full
401
402 // promotes a clause from redundant to irredundant. We do this for all
403 // clauses involved in gates to make sure that we produce correct result.
404 void promote_clause (Clause *);
405
406 // Merge functions. We actually need different several versions for LRAT
407 // in order to simplify the proof production.
408 //
409 // When merging binary clauses, we can simply produce the LRAT chain by
410 // (1) using the two binary clauses and (2) the reason clause from the
411 // literals to the representatives.
412 //
413 // The same approach does not work for merging gates because the
414 // representative might be also a representative of another literal
415 // (because of eager rewriting), requiring to resolve more than once on
416 // the same literal. An example of this are the two gates 4=-2&7 and
417 // 6=-2&1, the rewriting 7=1 and the equivalence 4=1. The simple road of
418 // merging 6 and 4 (requires resolving away 1) + adding the rewrite 4 to 1
419 // (requires adding 1) does not work.
420 //
421 // Therefore, we actually go for the more regular road and produce two
422 // equivalence: the merge from the LHS, followed by the actual equivalence
423 // (by combining it with the rewrite). In DRAT this is less important
424 // because the checker finds a chain and is less restricted than our LRAT
425 // chain.
426 bool merge_literals_equivalence (int lit, int other, Clause *c1,
427 Clause *c2);
428 bool merge_literals_lrat (Gate *g, Gate *h, int lit, int other,
429 const std::vector<LRAT_ID> & = {},
430 const std::vector<LRAT_ID> & = {});
431 bool merge_literals_lrat (int lit, int other,
432 const std::vector<LRAT_ID> & = {},
433 const std::vector<LRAT_ID> & = {});
434
435 // proof production
437 void push_lrat_id (const Clause *const c, int lit);
438 void push_lrat_unit (int lit);
439
440 // pushes the clause with the reasons to rewrite clause
441 // unless:
442 // - the rewriting is not necessary (resolvent_marked == 1)
443 // - it is overwritten by one of the arguments
445 std::vector<LRAT_ID> &chain,
446 bool = true,
447 Rewrite rewrite2 = Rewrite (),
448 int execept_lhs = 0,
449 int except_lhs2 = 0);
451 std::vector<LRAT_ID> &chain,
452 bool = true,
453 Rewrite rewrite2 = Rewrite (),
454 int execept_lhs = 0,
455 int except_lhs2 = 0);
456 // TODO: does nothing except pushing on the stack, remove!
457 void push_id_on_chain (std::vector<LRAT_ID> &chain, Clause *c);
458 // TODO: does nothing except pushing on the stack, remove!
459 void push_id_on_chain (std::vector<LRAT_ID> &chain,
460 const std::vector<LitClausePair> &c);
461 // TODO: does nothing except pushing on the stack, remove!
462 void push_id_on_chain (std::vector<LRAT_ID> &chain, Rewrite rewrite, int);
464 Gate *g, Gate *h, std::vector<LRAT_ID> &extra_reasons_lit,
465 std::vector<LRAT_ID> &extra_reasons_ulit, bool remove_units = true);
467 Gate *g, int src, LRAT_ID id1, LRAT_ID id2, int dst,
468 std::vector<LRAT_ID> &extra_reasons_lit,
469 std::vector<LRAT_ID> &extra_reasons_ulit);
470 // occs
472 GOccs &goccs (int lit);
473 void connect_goccs (Gate *g, int lit);
475 void mark_garbage (Gate *);
476 // remove the gate from the table
477 bool remove_gate (Gate *);
478 bool remove_gate (GatesTable::iterator git);
479 void index_gate (Gate *);
480
481 // second counter for size, complements noccs
482 uint64_t &largecount (int lit);
483
484 // simplification
485 bool skip_and_gate (Gate *g);
486 bool skip_xor_gate (Gate *g);
487 void update_and_gate (Gate *g, GatesTable::iterator, int src, int dst,
488 LRAT_ID id1, LRAT_ID id2, int falsified = 0,
489 int clashing = 0);
490 void update_xor_gate (Gate *g, GatesTable::iterator);
491 void shrink_and_gate (Gate *g, int falsified = 0, int clashing = 0);
492 bool simplify_gate (Gate *g);
493 void simplify_and_gate (Gate *g);
494 void simplify_ite_gate (Gate *g);
496 void simplify_xor_gate (Gate *g);
497 bool simplify_gates (int lit);
500 int except2 = 0, bool flip = 0);
502
503 // rewriting
504 bool rewriting_lhs (Gate *g, int dst);
505 bool rewrite_gates (int dst, int src, LRAT_ID id1, LRAT_ID id2);
506 bool rewrite_gate (Gate *g, int dst, int src, LRAT_ID id1, LRAT_ID id2);
507 void rewrite_xor_gate (Gate *g, int dst, int src);
508 void rewrite_and_gate (Gate *g, int dst, int src, LRAT_ID id1,
509 LRAT_ID id2);
510 void rewrite_ite_gate (Gate *g, int dst, int src);
511
512 size_t units; // next trail position to propagate
513 bool propagate_unit (int lit);
514 bool propagate_units ();
516 bool propagate_equivalence (int lit);
517
518 // gates
519 void init_closure ();
520 void reset_closure ();
521 void reset_extraction ();
524 void extract_gates ();
527 Gate *find_first_and_gate (Clause *base_clause, int lhs);
528 Gate *find_remaining_and_gate (Clause *base_clause, int lhs);
529 void extract_and_gates ();
530
531 Gate *find_and_lits (const vector<int> &rhs, Gate *except = nullptr);
532 // rhs is sorted, so passing by copy
534 Gate *except = nullptr);
536 // not const to normalize negations, also fixes the order of the LRAT
537 Gate *find_ite_gate (Gate *, bool &);
539
541 void init_xor_gate_extraction (std::vector<Clause*> &candidates);
543 void add_xor_matching_proof_chain (Gate *g, int lhs1,
544 const vector<LitClausePair> &,
545 int lhs2, vector<LRAT_ID> &,
547 void add_xor_shrinking_proof_chain (Gate *g, int src);
548 void extract_xor_gates ();
550 Clause *find_large_xor_side_clause (std::vector<int> &lits);
551
552 void merge_condeq (int cond, lit_equivalences &condeq,
553 lit_equivalences &not_condeq);
557 void check_ite_implied (int lhs, int cond, int then_lit, int else_lit);
560 void check_ite_lrat_reasons (Gate *g, bool = false);
561 void check_contained_module_rewriting (Clause *c, int lit, bool,
562 int except);
563 void delete_proof_chain ();
564
565 // ite gate extraction
567 void extract_ite_gates_of_variable (int idx);
570 void init_ite_gate_extraction (std::vector<ClauseSize> &candidates);
571 lit_implications::const_iterator find_lit_implication_second_literal (
572 int lit, lit_implications::const_iterator begin,
573 lit_implications::const_iterator end);
574 void search_condeq (int lit, int pos_lit,
575 lit_implications::const_iterator pos_begin,
576 lit_implications::const_iterator pos_end, int neg_lit,
577 lit_implications::const_iterator neg_begin,
578 lit_implications::const_iterator neg_end,
581 void extract_ite_gates ();
582
584
586
587 void add_ite_matching_proof_chain (Gate *g, Gate *h, int lhs1, int lhs2,
588 std::vector<LRAT_ID> &reasons1,
589 std::vector<LRAT_ID> &reasons2);
591 Gate *new_and_gate (Clause *, int);
592 Gate *new_ite_gate (int lhs, int cond, int then_lit, int else_lit,
593 std::vector<LitClausePair> &&clauses);
595 // check
596 void check_xor_gate_implied (Gate const *const);
597 void check_ternary (int a, int b, int c);
598 void check_binary_implied (int a, int b);
599 void check_implied ();
600
601 // learn units. You can delay units if you want to learn several at once before
602 // propagation. Otherwise, propagate! If you need propagation even if nothing is set, use the
603 // second parameter.
604 //
605 // The function can also learn the empty clause if the unit is already set. Do not add the unit in
606 // the chain!
607 bool learn_congruence_unit (int unit, bool = false, bool = false);
608 bool fully_propagate ();
610 int dst,
611 int clashing,
612 int falsified, int unit);
613 void learn_congruence_unit_when_lhs_set (Gate *g, int src, LRAT_ID id1,
614 LRAT_ID id2, int dst);
615
616 void find_units ();
617 void find_equivalences ();
618 void subsume_clause (Clause *subsuming, Clause *subsumed);
621 int execept_lhs = 0,
622 bool = true);
623 // rewrite the clause using eager rewriting and rew1 and rew2, except for
624 // 2 literals Usage:
625 // - the except are used to ignore LHS of gates that have not and should
626 // not be rewritten.
627 // - TODO: except_lhs2 should never be used actually
628 // - the Rewrite are for additional rewrite to allow for lazy rewrites
629 // to be taken into account without being added to the eager rewriting
630 // (yet)
631 Clause *produce_rewritten_clause_lrat (Clause *c, int execept_lhs = 0,
632 bool remove_units = true, bool = true);
634 int execept_lhs = 0,
635 bool = true);
636 void compute_rewritten_clause_lrat_simple (Clause *c, int except);
637 // variant where we update the indices after removing the tautologies and
638 // remove the tautological clauses
640 std::vector<LitClausePair> &litIds, int except_lhs,
641 size_t &old_position1, size_t &old_position2,
642 bool remove_units = true);
643 // binary extraction and ternary strengthening
644 void extract_binaries ();
645 bool find_binary (int, int) const;
646
647 Clause *new_tmp_clause (std::vector<int> &clause);
650 Clause *new_clause ();
651 //
653 void sort_literals_by_var_except (vector<int> &rhs, int, int except2 = 0);
654
655 // schedule
657 void schedule_literal (int lit);
658 void add_clause_to_chain (std::vector<int>, LRAT_ID);
659 // proof. If delete_id is non-zero, then delete the clause instead of
660 // learning it
662 LRAT_ID delete_id = 0);
663
664 // we define our own wrapper as cadical has otherwise a non-compatible
665 // marking system
666 signed char &marked (int lit);
667 void set_mu1_reason (int lit, Clause *c);
668 void set_mu2_reason (int lit, Clause *c);
669 void set_mu4_reason (int lit, Clause *c);
673
674 // XOR
675 uint32_t number_from_xor_reason_reversed (const std::vector<int> &rhs);
676 uint32_t number_from_xor_reason (const std::vector<int> &rhs, int,
677 int except2 = 0, bool flip = 0);
678 void gate_sort_lrat_reasons (std::vector<LitClausePair> &, int,
679 int except2 = 0, bool flip = 0);
680 void gate_sort_lrat_reasons (LitClausePair &, int, int except2 = 0,
681 bool flip = 0);
682
683 bool rewrite_ite_gate_to_and (Gate *g, int dst, int src, size_t c,
684 size_t d, int cond_lit_to_learn_if_degenerated);
686 Gate *g, int dst, int src, std::vector<LRAT_ID> &reasons_implication,
687 std::vector<LRAT_ID> &reasons_back);
689 Gate *g, std::vector<LRAT_ID> &reasons_implication,
690 std::vector<LRAT_ID> &reasons_back,
691 std::vector<LRAT_ID> &reasons_unit, bool, bool &);
692 void rewrite_ite_gate_update_lrat_reasons (Gate *g, int src, int dst);
693 void simplify_ite_gate_produce_unit_lrat (Gate *g, int lit, size_t idx1,
694 size_t idx2);
696 Gate *g, Gate *h, std::vector<LRAT_ID> &reasons_lrat,
697 std::vector<LRAT_ID> &reasons_lrat_back, bool remove_units = true);
698 // first index is a binary clause after unit propagation and the second
699 // has length 3
700 bool simplify_ite_gate_to_and (Gate *g, size_t idx1, size_t idx2,
701 int removed);
702 void
703 merge_ite_gate_same_then_else_lrat (std::vector<LitClausePair> &clauses,
704 std::vector<LRAT_ID> &reasons_implication,
705 std::vector<LRAT_ID> &reasons_back);
707 Gate *g, std::vector<LRAT_ID> &reasons_implication,
708 std::vector<LRAT_ID> &reasons_back, size_t idx1, size_t idx2);
709
711 Gate *g, std::vector<LRAT_ID> &reasons_lrat,
712 std::vector<LRAT_ID> &reasons_back_lrat, size_t idx1, size_t idx2);
714};
715
716} // namespace CaDiCaL
717
719
720#endif
unsigned int uint32_t
Definition Fxch.h:32
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define add_ite_matching_proof_chain(...)
#define check_ternary
Definition congruence.c:728
#define check_and_gate_implied(...)
Definition congruence.c:723
#define add_xor_shrinking_proof_chain(...)
#define add_ite_turned_and_binary_clauses
#define check_ite_implied
Definition congruence.c:729
#define add_xor_matching_proof_chain(...)
#define check_ite_gate_implied
Definition congruence.c:730
#define check_xor_gate_implied
Definition congruence.c:727
bool ite_flags_neg_cond_lhs(int8_t flag)
bool ite_flags_cond_lhs(int8_t flag)
std::vector< lit_equivalence > lit_equivalences
std::vector< lit_implication > lit_implications
bool ite_flags_no_then_clauses(int8_t flag)
bool ite_flags_no_else_clauses(int8_t flag)
vector< Gate * > GOccs
std::string string_of_gate(Gate_Type t)
int64_t LRAT_ID
int lit
Definition satVec.h:130
ClauseSize(int s, Clause *c)
vector< LRAT_ID > eager_representant_id
LRAT_ID & representative_id(int lit)
void simplify_ite_gate_condition_set(Gate *g, std::vector< LRAT_ID > &reasons_lrat, std::vector< LRAT_ID > &reasons_back_lrat, size_t idx1, size_t idx2)
vector< int > lits
Gate * find_xor_gate(Gate *)
void produce_representative_lrat(int lit)
vector< LRAT_ID > lrat_chain
void simplify_xor_gate(Gate *g)
void search_condeq(int lit, int pos_lit, lit_implications::const_iterator pos_begin, lit_implications::const_iterator pos_end, int neg_lit, lit_implications::const_iterator neg_begin, lit_implications::const_iterator neg_end, lit_equivalences &condeq)
Gate * find_ite_gate(Gate *, bool &)
void merge_condeq(int cond, lit_equivalences &condeq, lit_equivalences &not_condeq)
bool simplify_ite_gate_to_and(Gate *g, size_t idx1, size_t idx2, int removed)
vector< int > unsimplified
Gate * new_xor_gate(const vector< LitClausePair > &, int)
vector< LitClausePair > lrat_chain_and_gate
vector< int > chain
bool rewriting_lhs(Gate *g, int dst)
Gate * find_and_lits(const vector< int > &rhs, Gate *except=nullptr)
void simplify_and_gate(Gate *g)
void simplify_unit_xor_lrat_clauses(const vector< LitClausePair > &, int)
Clause * learn_binary_tmp_or_full_clause(int a, int b)
Clause * add_tmp_binary_clause(int a, int b)
LRAT_ID find_eager_representative_lrat(int lit)
int & representative(int lit)
void extract_ite_gates_of_variable(int idx)
vector< GOccs > gtab
void set_mu4_reason(int lit, Clause *c)
void set_mu2_reason(int lit, Clause *c)
LRAT_ID simplify_and_add_to_proof_chain(vector< int > &unsimplified, LRAT_ID delete_id=0)
void produce_eager_representative_lrat(int lit)
void merge_ite_gate_same_then_else_lrat(std::vector< LitClausePair > &clauses, std::vector< LRAT_ID > &reasons_implication, std::vector< LRAT_ID > &reasons_back)
Clause * find_large_xor_side_clause(std::vector< int > &lits)
void push_id_and_rewriting_lrat_unit(Clause *c, Rewrite rewrite1, std::vector< LRAT_ID > &chain, bool=true, Rewrite rewrite2=Rewrite(), int execept_lhs=0, int except_lhs2=0)
unordered_set< Gate *, Hash, GateEqualTo > GatesTable
void compute_rewritten_clause_lrat_simple(Clause *c, int except)
void init_xor_gate_extraction(std::vector< Clause * > &candidates)
vector< int > representant
void check_binary_implied(int a, int b)
Clause * simplify_xor_clause(int lhs, Clause *)
char & lazy_propagated(int lit)
void push_id_on_chain(std::vector< LRAT_ID > &chain, Clause *c)
void push_lrat_unit(int lit)
void push_id_and_rewriting_lrat_full(Clause *c, Rewrite rewrite1, std::vector< LRAT_ID > &chain, bool=true, Rewrite rewrite2=Rewrite(), int execept_lhs=0, int except_lhs2=0)
void merge_and_gate_lrat_produce_lrat(Gate *g, Gate *h, std::vector< LRAT_ID > &reasons_lrat, std::vector< LRAT_ID > &reasons_lrat_back, bool remove_units=true)
uint64_t & new_largecounts(int lit)
std::array< lit_equivalences, 2 > condeq
void rewrite_xor_gate(Gate *g, int dst, int src)
void update_and_gate_unit_build_lrat_chain(Gate *g, int src, LRAT_ID id1, LRAT_ID id2, int dst, std::vector< LRAT_ID > &extra_reasons_lit, std::vector< LRAT_ID > &extra_reasons_ulit)
void shrink_and_gate(Gate *g, int falsified=0, int clashing=0)
bool rewrite_gates(int dst, int src, LRAT_ID id1, LRAT_ID id2)
std::array< int, 16 > nonces
vector< uint64_t > glargecounts
int find_representative_and_compress(int, bool update_eager=true)
bool normalize_ite_lits_gate(Gate *rhs)
void produce_ite_merge_lhs_then_else_reasons(Gate *g, std::vector< LRAT_ID > &reasons_implication, std::vector< LRAT_ID > &reasons_back, std::vector< LRAT_ID > &reasons_unit, bool, bool &)
void extract_xor_gates_with_base_clause(Clause *c)
void import_lazy_and_find_eager_representative_and_compress_both(int)
Gate * find_first_and_gate(Clause *base_clause, int lhs)
void learn_congruence_unit_when_lhs_set(Gate *g, int src, LRAT_ID id1, LRAT_ID id2, int dst)
uint32_t number_from_xor_reason(const std::vector< int > &rhs, int, int except2=0, bool flip=0)
std::array< lit_implications, 2 > condbin
void check_contained_module_rewriting(Clause *c, int lit, bool, int except)
LRAT_ID & eager_representative_id(int lit)
vector< signed char > marks
vector< int > eager_representant
void update_and_gate(Gate *g, GatesTable::iterator, int src, int dst, LRAT_ID id1, LRAT_ID id2, int falsified=0, int clashing=0)
int find_lrat_representative_with_marks(int lit)
queue< int > schedule
LitClausePair marked_mu1(int lit)
void produce_rewritten_clause_lrat(vector< LitClausePair > &, int execept_lhs=0, bool=true)
Clause * maybe_add_binary_clause(int a, int b)
vector< CompactBinary > binaries
bool learn_congruence_unit(int unit, bool=false, bool=false)
void learn_congruence_unit_falsifies_lrat_chain(Gate *g, int src, int dst, int clashing, int falsified, int unit)
bool rewrite_gate(Gate *g, int dst, int src, LRAT_ID id1, LRAT_ID id2)
void init_ite_gate_extraction(std::vector< ClauseSize > &candidates)
vector< Clause * > extra_clauses
vector< LRAT_ID > representant_id
void sort_literals_by_var(vector< int > &rhs)
void extract_and_gates(Closure &)
bool merge_literals_lrat(Gate *g, Gate *h, int lit, int other, const std::vector< LRAT_ID > &={}, const std::vector< LRAT_ID > &={})
Internal *const internal
bool find_binary(int, int) const
void check_not_tmp_binary_clause(Clause *c)
vector< int > resolvent_analyzed
void simplify_ite_gate_produce_unit_lrat(Gate *g, int lit, size_t idx1, size_t idx2)
int find_eager_representative_and_compress(int)
void produce_rewritten_clause_lrat_and_clean(vector< LitClausePair > &, int execept_lhs=0, bool=true)
uint64_t & largecount(int lit)
bool merge_literals_equivalence(int lit, int other, Clause *c1, Clause *c2)
void rewrite_ite_gate_update_lrat_reasons(Gate *g, int src, int dst)
vector< int > clause
Gate * new_ite_gate(int lhs, int cond, int then_lit, int else_lit, std::vector< LitClausePair > &&clauses)
vector< int > rhs
void rewrite_ite_gate(Gate *g, int dst, int src)
void update_and_gate_build_lrat_chain(Gate *g, Gate *h, std::vector< LRAT_ID > &extra_reasons_lit, std::vector< LRAT_ID > &extra_reasons_ulit, bool remove_units=true)
int & eager_representative(int lit)
void push_lrat_id(const Clause *const c, int lit)
lit_implications::const_iterator find_lit_implication_second_literal(int lit, lit_implications::const_iterator begin, lit_implications::const_iterator end)
void check_ite_lrat_reasons(Gate *g, bool=false)
void simplify_ite_gate(Gate *g)
bool rewrite_ite_gate_to_and(Gate *g, int dst, int src, size_t c, size_t d, int cond_lit_to_learn_if_degenerated)
uint64_t & largecounts(int lit)
void rewrite_and_gate(Gate *g, int dst, int src, LRAT_ID id1, LRAT_ID id2)
void promote_clause(Clause *)
LitClausePair marked_mu2(int lit)
LRAT_ID check_and_add_to_proof_chain(vector< int > &clause)
uint32_t number_from_xor_reason_reversed(const std::vector< int > &rhs)
void add_clause_to_chain(std::vector< int >, LRAT_ID)
Clause * maybe_promote_tmp_binary_clause(Clause *)
void extract_congruence()
void simplify_and_sort_xor_lrat_clauses(const vector< LitClausePair > &, vector< LitClausePair > &, int, int except2=0, bool flip=0)
vector< uint64_t > gnew_largecounts
void schedule_literal(int lit)
int find_representative(int lit)
void extract_ite_gates_of_literal(int)
void produce_ite_merge_then_else_reasons(Gate *g, int dst, int src, std::vector< LRAT_ID > &reasons_implication, std::vector< LRAT_ID > &reasons_back)
LitClausePair marked_mu4(int lit)
bool find_subsuming_clause(Clause *c)
void find_conditional_equivalences(int lit, lit_implications &condbin, lit_equivalences &condeq)
std::vector< std::pair< size_t, size_t > > offsetsize
std::vector< char > lazy_propagated_idx
size_t propagate_units_and_equivalences()
void gate_sort_lrat_reasons(std::vector< LitClausePair > &, int, int except2=0, bool flip=0)
void update_xor_gate(Gate *g, GatesTable::iterator)
vector< bool > scheduled
void connect_goccs(Gate *g, int lit)
Clause * add_binary_clause(int a, int b)
void subsume_clause(Clause *subsuming, Clause *subsumed)
void sort_literals_by_var_except(vector< int > &rhs, int, int except2=0)
LRAT_ID find_representative_lrat(int lit)
Gate * find_gate_lits(const vector< int > &rhs, Gate_Type typ, Gate *except=nullptr)
Gate * new_and_gate(Clause *, int)
void find_representative_and_compress_both(int)
vector< LitClausePair > mu2_ids
Clause * new_tmp_clause(std::vector< int > &clause)
void simplify_ite_gate_then_else_set(Gate *g, std::vector< LRAT_ID > &reasons_implication, std::vector< LRAT_ID > &reasons_back, size_t idx1, size_t idx2)
bool propagate_equivalence(int lit)
std::vector< Clause * > new_unwatched_binary_clauses
void set_mu1_reason(int lit, Clause *c)
Clause * produce_rewritten_clause_lrat(Clause *c, int execept_lhs=0, bool remove_units=true, bool=true)
signed char & marked(int lit)
void copy_conditional_equivalences(int lit, lit_implications &condbin)
vector< LitClausePair > mu1_ids
void extract_and_gates_with_base_clause(Clause *c)
vector< Gate * > garbage
vector< LitClausePair > mu4_ids
Gate * find_remaining_and_gate(Clause *base_clause, int lhs)
void extract_condeq_pairs(int lit, lit_implications &condbin, lit_equivalences &condeq)
Gate * find_xor_lits(const vector< int > &rhs)
CompactBinary(Clause *c, LRAT_ID i, int l1, int l2)
bool operator()(const Gate *const lhs, const Gate *const rhs) const
vector< int > rhs
bool degenerated_and_neg
bool operator==(Gate const &lhs)
int8_t degenerated_ite
vector< LitClausePair > pos_lhs_ids
Gate_Type tag
vector< LitClausePair > neg_lhs_ids
bool degenerated_and_pos
size_t arity() const
size_t operator()(const Gate *const g) const
Hash(std::array< int, 16 > &ncs)
std::array< int, 16 > & nonces
LitClausePair(int lit, Clause *cl)
LitIdPair(int l, LRAT_ID i)
Rewrite(int _src, int _dst, LRAT_ID _id1, LRAT_ID _id2)
lit_equivalence(int f, Clause *f_id, int s, Clause *s_id)
lit_equivalence swap()
lit_equivalence negate_both()
lit_equivalence(int f, int s)
lit_implication(int f, int s)
lit_implication(int f, int s, Clause *_id)
Type operator()(const ClauseSize &a)
Definition queue.h:20