/* Boolector: Satisfiability Modulo Theories (SMT) solver. * * Copyright (C) 2007-2021 by the authors listed in the AUTHORS file. * * This file is part of Boolector. * See COPYING for more information on using this software. */ #ifndef BTORAIG_H_INCLUDED #define BTORAIG_H_INCLUDED #include "btoropt.h" #include "btorsat.h" #include "btortypes.h" #include "utils/btorhashptr.h" #include "utils/btormem.h" #include "utils/btorstack.h" #include #include struct BtorAIGMap; /*------------------------------------------------------------------------*/ struct BtorAIG { int32_t id; int32_t cnf_id; uint32_t refs; int32_t next; /* next AIG id for unique table */ uint8_t mark : 2; uint8_t is_var : 1; /* is it an AIG variable or an AND? */ uint32_t local; int32_t children[]; /* only allocated for AIG AND */ }; typedef struct BtorAIG BtorAIG; BTOR_DECLARE_STACK (BtorAIGPtr, BtorAIG *); struct BtorAIGUniqueTable { uint32_t size; uint32_t num_elements; int32_t *chains; }; typedef struct BtorAIGUniqueTable BtorAIGUniqueTable; struct BtorAIGMgr { Btor *btor; BtorAIGUniqueTable table; BtorSATMgr *smgr; BtorAIGPtrStack id2aig; /* id to AIG node */ BtorIntStack cnfid2aig; /* cnf id to AIG id */ uint_least64_t cur_num_aigs; /* current number of ANDs */ uint_least64_t cur_num_aig_vars; /* current number of AIG variables */ /* statistics */ uint_least64_t max_num_aigs; uint_least64_t max_num_aig_vars; uint_least64_t num_cnf_vars; uint_least64_t num_cnf_clauses; uint_least64_t num_cnf_literals; }; typedef struct BtorAIGMgr BtorAIGMgr; /*------------------------------------------------------------------------*/ #define BTOR_AIG_FALSE ((BtorAIG *) (uintptr_t) 0) #define BTOR_AIG_TRUE ((BtorAIG *) (uintptr_t) 1) #define BTOR_INVERT_AIG(aig) ((BtorAIG *) ((uintptr_t) 1 ^ (uintptr_t) (aig))) #define BTOR_IS_INVERTED_AIG(aig) ((uintptr_t) 1 & (uintptr_t) (aig)) #define BTOR_REAL_ADDR_AIG(aig) \ ((BtorAIG *) ((~(uintptr_t) 1) & (uintptr_t) (aig))) #define BTOR_IS_REGULAR_AIG(aig) (!((uintptr_t) 1 & (uintptr_t) (aig))) /*------------------------------------------------------------------------*/ static inline bool btor_aig_is_const (const BtorAIG *aig) { return aig == BTOR_AIG_TRUE || aig == BTOR_AIG_FALSE; } static inline bool btor_aig_is_false (const BtorAIG *aig) { return aig == BTOR_AIG_FALSE; } static inline bool btor_aig_is_true (const BtorAIG *aig) { return aig == BTOR_AIG_TRUE; } static inline bool btor_aig_is_var (const BtorAIG *aig) { if (btor_aig_is_const (aig)) return false; return aig->is_var; } static inline bool btor_aig_is_and (const BtorAIG *aig) { if (btor_aig_is_const (aig)) return false; return !aig->is_var; } static inline int32_t btor_aig_get_id (const BtorAIG *aig) { assert (aig); assert (!btor_aig_is_const (aig)); return BTOR_IS_INVERTED_AIG (aig) ? -BTOR_REAL_ADDR_AIG (aig)->id : aig->id; } static inline BtorAIG * btor_aig_get_by_id (BtorAIGMgr *amgr, int32_t id) { assert (amgr); return id < 0 ? BTOR_INVERT_AIG (BTOR_PEEK_STACK (amgr->id2aig, -id)) : BTOR_PEEK_STACK (amgr->id2aig, id); } static inline int32_t btor_aig_get_cnf_id (const BtorAIG *aig) { if (btor_aig_is_true (aig)) return 1; if (btor_aig_is_false (aig)) return -1; return BTOR_IS_INVERTED_AIG (aig) ? -BTOR_REAL_ADDR_AIG (aig)->cnf_id : aig->cnf_id; } static inline BtorAIG * btor_aig_get_left_child (BtorAIGMgr *amgr, const BtorAIG *aig) { assert (amgr); assert (aig); assert (!btor_aig_is_const (aig)); return btor_aig_get_by_id (amgr, BTOR_REAL_ADDR_AIG (aig)->children[0]); } static inline BtorAIG * btor_aig_get_right_child (BtorAIGMgr *amgr, const BtorAIG *aig) { assert (amgr); assert (aig); assert (!btor_aig_is_const (aig)); return btor_aig_get_by_id (amgr, BTOR_REAL_ADDR_AIG (aig)->children[1]); } /*------------------------------------------------------------------------*/ BtorAIGMgr *btor_aig_mgr_new (Btor *btor); BtorAIGMgr *btor_aig_mgr_clone (Btor *btor, BtorAIGMgr *amgr); void btor_aig_mgr_delete (BtorAIGMgr *amgr); BtorSATMgr *btor_aig_get_sat_mgr (const BtorAIGMgr *amgr); /* Variable representing 1 bit. */ BtorAIG *btor_aig_var (BtorAIGMgr *amgr); /* Inverter. */ BtorAIG *btor_aig_not (BtorAIGMgr *amgr, BtorAIG *aig); /* Logical AND. */ BtorAIG *btor_aig_and (BtorAIGMgr *amgr, BtorAIG *left, BtorAIG *right); /* Logical OR. */ BtorAIG *btor_aig_or (BtorAIGMgr *amgr, BtorAIG *left, BtorAIG *right); /* Logical EQUIVALENCE. */ BtorAIG *btor_aig_eq (BtorAIGMgr *amgr, BtorAIG *left, BtorAIG *right); /* If then Else. */ BtorAIG *btor_aig_cond (BtorAIGMgr *amgr, BtorAIG *aig_cond, BtorAIG *aig_if, BtorAIG *aig_else); /* Copies AIG (increments reference counter). */ BtorAIG *btor_aig_copy (BtorAIGMgr *amgr, BtorAIG *aig); /* Releases AIG (decrements reference counter). * If reference counter reaches 0, * then also the children are released * and AIG is deleted from memory. */ void btor_aig_release (BtorAIGMgr *amgr, BtorAIG *aig); /* Translates AIG into SAT instance. */ void btor_aig_to_sat (BtorAIGMgr *amgr, BtorAIG *aig); /* As 'btor_aig_to_sat' but also add the argument as new SAT constraint. * Actually this will result in less constraints being generated. */ void btor_aig_add_toplevel_to_sat (BtorAIGMgr *, BtorAIG *); /* Translates AIG into SAT instance in both phases. * The function guarantees that after finishing every reachable AIG * has a CNF id. */ void btor_aig_to_sat_tseitin (BtorAIGMgr *amgr, BtorAIG *aig); /* Gets current assignment of AIG aig (in the SAT case). */ int32_t btor_aig_get_assignment (BtorAIGMgr *amgr, BtorAIG *aig); /* Orders AIGs (actually assume left child of an AND node is smaller * than right child */ int32_t btor_aig_compare (const BtorAIG *aig0, const BtorAIG *aig1); /* hash AIG by id */ uint32_t btor_aig_hash_by_id (const BtorAIG *aig); /* compare AIG by id */ int32_t btor_aig_compare_by_id (const BtorAIG *aig0, const BtorAIG *aig1); int32_t btor_compare_aig_by_id_qsort_asc (const void *aig0, const void *aig1); #endif