// set wrappers DenseSet Lx_set (Ob lhs) const { return DenseSet(item_dim(), const_cast<std::atomic<Word> *>(Lx(lhs))); }
DenseSet Rx_set (Ob rhs) const { return DenseSet(item_dim(), const_cast<std::atomic<Word> *>(Rx(rhs))); }
Approximator::Approximator(Structure& structure, DenseSetStore& sets, WorkerPool& worker_pool) : // structure m_structure(structure), m_item_dim(structure.carrier().item_dim()), m_top(structure.nullary_function("TOP").find()), m_bot(structure.nullary_function("BOT").find()), m_less(structure.binary_relation("LESS")), m_nless(structure.binary_relation("NLESS")), // dense set stores m_sets(sets), m_empty_set(sets.store(std::move(DenseSet(m_item_dim)))), m_known(1 + m_item_dim), m_unknown(), // lazy map caches m_disjoint_cache(worker_pool, [this](const std::pair<SetId, SetId>& pair) { return m_sets.load(pair.first).disjoint(m_sets.load(pair.second)) ? Trool::TRUE : Trool::FALSE; }), m_union_cache(worker_pool, [this](const std::vector<SetId>& sets) { const size_t count = sets.size(); POMAGMA_ASSERT1(count >= 2, "too few sets: " << count); DenseSet val(m_item_dim); val.set_union(m_sets.load(sets[0]), m_sets.load(sets[1])); for (size_t i = 2; i < count; ++i) { val += m_sets.load(sets[i]); } return m_sets.store(std::move(val)); }), m_nullary_cache(), m_binary_cache() { POMAGMA_ASSERT(m_top, "TOP is not defined"); POMAGMA_ASSERT(m_bot, "BOT is not defined"); POMAGMA_INFO("Inserting LESS and NLESS in DenseSetStore"); for (auto iter = m_structure.carrier().iter(); iter.ok(); iter.next()) { const Ob ob = *iter; m_known[ob][ABOVE] = m_sets.store(m_less.get_Lx_set(ob)); m_known[ob][BELOW] = m_sets.store(m_less.get_Rx_set(ob)); m_known[ob][NABOVE] = m_sets.store(m_nless.get_Lx_set(ob)); m_known[ob][NBELOW] = m_sets.store(m_nless.get_Rx_set(ob)); } m_unknown[ABOVE] = m_known[m_top][ABOVE]; m_unknown[BELOW] = m_known[m_bot][BELOW]; m_unknown[NABOVE] = m_empty_set; m_unknown[NBELOW] = m_empty_set; POMAGMA_INFO("Initializing nullary_function cache"); for (const auto& i : signature().nullary_functions()) { const std::string& name = i.first; Ob ob = i.second->find(); Approximation approx = ob ? known(ob) : unknown(); POMAGMA_INSERT(m_nullary_cache, name, approx); } POMAGMA_INFO("Initializing binary_function cache"); for (const auto& i : signature().binary_functions()) { const auto& fun = *i.second; const uint64_t hash = hash_name(i.first); typedef SetPairToSetCache Cache; for (Parity p : {ABOVE, BELOW}) { POMAGMA_INSERT( m_binary_cache, CacheKey(hash, VAL, p), new Cache(worker_pool, [this, &fun, p](const std::pair<SetId, SetId>& x) { return function_lhs_rhs(fun, x.first, x.second, p); })); } for (Parity p : {NABOVE, NBELOW}) { POMAGMA_INSERT( m_binary_cache, CacheKey(hash, RHS, p), new Cache(worker_pool, [this, &fun, p](const std::pair<SetId, SetId>& x) { return function_lhs_val(fun, x.first, x.second, p); })); POMAGMA_INSERT( m_binary_cache, CacheKey(hash, LHS, p), new Cache(worker_pool, [this, &fun, p](const std::pair<SetId, SetId>& x) { return function_rhs_val(fun, x.first, x.second, p); })); } } POMAGMA_INFO("Initializing symmetric_function cache"); for (const auto& i : signature().symmetric_functions()) { const auto& fun = *i.second; const uint64_t hash = hash_name(i.first); typedef SetPairToSetCache Cache; for (Parity p : {ABOVE, BELOW}) { POMAGMA_INSERT( m_binary_cache, CacheKey(hash, VAL, p), new Cache(worker_pool, [this, &fun, p](const std::pair<SetId, SetId>& x) { return function_lhs_rhs(fun, x.first, x.second, p); })); } for (Parity p : {NABOVE, NBELOW}) { auto* cache = new Cache( worker_pool, [this, &fun, p](const std::pair<SetId, SetId>& x) { return function_lhs_val(fun, x.first, x.second, p); }); POMAGMA_INSERT(m_binary_cache, CacheKey(hash, RHS, p), cache); POMAGMA_INSERT(m_binary_cache, CacheKey(hash, LHS, p), cache); } } }