Beispiel #1
0
Approximator::Approximator(Structure& 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_identity(structure.nullary_function("I").find()),
      m_less(structure.binary_relation("LESS")),
      m_nless(structure.binary_relation("NLESS")),
      m_join(structure.signature().symmetric_function("JOIN")),
      m_rand(structure.signature().symmetric_function("RAND")),
      m_quote(structure.signature().injective_function("QUOTE")) {
    POMAGMA_ASSERT(m_top, "TOP is not defined");
    POMAGMA_ASSERT(m_bot, "BOT is not defined");
    POMAGMA_ASSERT(m_identity, "I is not defined");
}
Beispiel #2
0
std::vector<Ob> conjecture_diverge(Structure& structure,
                                   const std::vector<float>& probs,
                                   const std::vector<std::string>& routes,
                                   const char* conjectures_file) {
    POMAGMA_INFO("Conjecturing divergent terms");
    const Carrier& carrier = structure.carrier();
    const BinaryRelation& NLESS = structure.binary_relation("NLESS");
    const Ob BOT = structure.nullary_function("BOT").find();
    const Ob TOP = structure.nullary_function("TOP").find();

    POMAGMA_DEBUG("collecting conjectures");
    DenseSet conjecture_set(carrier.item_count());
    conjecture_set.set_diff(carrier.support(), NLESS.get_Rx_set(BOT));
    POMAGMA_ASSERT(conjecture_set.contains(BOT), "BOT not conjectured");
    POMAGMA_ASSERT(not conjecture_set.contains(TOP), "TOP conjectured");
    conjecture_set.remove(BOT);
    std::vector<Ob> conjectures;
    for (auto iter = conjecture_set.iter(); iter.ok(); iter.next()) {
        Ob ob = *iter;
        conjectures.push_back(ob);
    }

    POMAGMA_DEBUG("sorting " << conjectures.size() << " conjectures");
    std::sort(conjectures.begin(), conjectures.end(),
              [&](const Ob& x, const Ob& y) { return probs[x] > probs[y]; });

    POMAGMA_DEBUG("writing conjectures to " << conjectures_file);
    std::ofstream file(conjectures_file, std::ios::out | std::ios::trunc);
    POMAGMA_ASSERT(file, "failed to open " << conjectures_file);
    file << "# divergence conjectures generated by pomagma";
    for (auto ob : conjectures) {
        file << "\nEQUAL BOT " << routes[ob];
    }

    return conjectures;
}
Beispiel #3
0
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);
        }
    }
}