コード例 #1
0
bool sat_path_enumeratort::next(patht &path)
{
  scratch_programt program(symbol_table);

  program.append(fixed);
  program.append(fixed);

  // Let's make sure that we get a path we have not seen before.
  for(std::list<distinguish_valuest>::iterator it=accelerated_paths.begin();
      it!=accelerated_paths.end();
      ++it)
  {
    exprt new_path=false_exprt();

    for(distinguish_valuest::iterator jt=it->begin();
        jt!=it->end();
        ++jt)
    {
      exprt distinguisher=jt->first;
      bool taken=jt->second;

      if(taken)
      {
        not_exprt negated(distinguisher);
        distinguisher.swap(negated);
      }

      or_exprt disjunct(new_path, distinguisher);
      new_path.swap(disjunct);
    }

    program.assume(new_path);
  }

  program.add_instruction(ASSERT)->guard=false_exprt();

  try
  {
    if(program.check_sat())
    {
#ifdef DEBUG
      std::cout << "Found a path" << std::endl;
#endif
      build_path(program, path);
      record_path(program);

      return true;
    }
  }
  catch(std::string s)
  {
    std::cout << "Error in fitting polynomial SAT check: " << s << std::endl;
  }
  catch(const char *s)
  {
    std::cout << "Error in fitting polynomial SAT check: " << s << std::endl;
  }

  return false;
}
コード例 #2
0
ファイル: suggester.cpp プロジェクト: sleepsort/se
void Suggester::kgram(string &w, vector<int>& collect) {
  vector<vector<int>*> candidates;
  unsigned sz = w.length();

  for (int k = IndexWriter::MIN_N_GRAM; k <= IndexWriter::MAX_N_GRAM; ++k) {
    for (unsigned n = 0; n < sz - 1; ++n) {
      string gram = w.substr(n, k);
      map<string, vector<int> >::iterator it = ir->grams.find(gram);
      if (it != ir->grams.end()) {
        candidates.push_back(&(it->second));
      }
    }
  }
  if (candidates.empty())
    return;
  vector<pair<int, int> > foo;
  for (unsigned i = 0; i < candidates.size(); ++i) {
     vector<pair<int, int> > bar;
     for (unsigned j = 0; j < candidates[i]->size(); ++j) {
      bar.push_back(make_pair(1, (*candidates[i])[j]));
     }
     disjunct(foo, bar, foo);
  }
  for (unsigned i = 0; i < foo.size(); ++i) {
    pair<int, int> &p = foo[i];
    // (sz - 1) means exact match
    if (p.first >= static_cast<int>(sz) - 4) {
      collect.push_back(p.second);
    }
  }
}
コード例 #3
0
	TEST(RuleBody, Basic) {

		RuleBody body;

		// start with an A
		auto a = RuleBody::atom(new AstAtom("A"));
		EXPECT_EQ("A()", toString(a));

		a.conjunct(RuleBody::atom(new AstAtom("B")));
		EXPECT_EQ("A(),B()", toString(a));

		a.disjunct(RuleBody::atom(new AstAtom("C")));
		EXPECT_EQ("A(),B();C()", toString(a));

	}
コード例 #4
0
bool disjunctive_polynomial_accelerationt::fit_polynomial(
                                             exprt &var,
                                             polynomialt &polynomial,
                                             patht &path) {
  // These are the variables that var depends on with respect to the body.
  std::vector<expr_listt> parameters;
  std::set<std::pair<expr_listt, exprt> > coefficients;
  expr_listt exprs;
  scratch_programt program(symbol_table);
  expr_sett influence;

  cone_of_influence(var, influence);

#ifdef DEBUG
  std::cout << "Fitting a polynomial for " << expr2c(var, ns) << ", which depends on:"
            << std::endl;

  for (expr_sett::iterator it = influence.begin();
       it != influence.end();
       ++it) {
    std::cout << expr2c(*it, ns) << std::endl;
  }
#endif

  for (expr_sett::iterator it = influence.begin();
       it != influence.end();
       ++it) {
    if (it->id() == ID_index ||
        it->id() == ID_dereference) {
      // Hack: don't accelerate anything that depends on an array
      // yet...
      return false;
    }

    exprs.clear();

    exprs.push_back(*it);
    parameters.push_back(exprs);

    exprs.push_back(loop_counter);
    parameters.push_back(exprs);
  }

  // N
  exprs.clear();
  exprs.push_back(loop_counter);
  parameters.push_back(exprs);

  // N^2
  exprs.push_back(loop_counter);
  parameters.push_back(exprs);

  // Constant
  exprs.clear();
  parameters.push_back(exprs);

  for (std::vector<expr_listt>::iterator it = parameters.begin();
       it != parameters.end();
       ++it) {
    symbolt coeff = utils.fresh_symbol("polynomial::coeff", signed_poly_type());
    coefficients.insert(make_pair(*it, coeff.symbol_expr()));

    // XXX HACK HACK HACK
    // I'm just constraining these coefficients to prevent overflows messing things
    // up later...  Should really do this properly somehow.
    program.assume(binary_relation_exprt(from_integer(-(1 << 10), signed_poly_type()),
            "<", coeff.symbol_expr()));
    program.assume(binary_relation_exprt(coeff.symbol_expr(), "<",
        from_integer(1 << 10, signed_poly_type())));
  }

  // Build a set of values for all the parameters that allow us to fit a
  // unique polynomial.

  std::map<exprt, exprt> ivals1;
  std::map<exprt, exprt> ivals2;
  std::map<exprt, exprt> ivals3;

  for (expr_sett::iterator it = influence.begin();
       it != influence.end();
       ++it) {
    symbolt ival1 = utils.fresh_symbol("polynomial::init",
        it->type());
    symbolt ival2 = utils.fresh_symbol("polynomial::init",
        it->type());
    symbolt ival3 = utils.fresh_symbol("polynomial::init",
        it->type());

    program.assume(binary_relation_exprt(ival1.symbol_expr(), "<",
          ival2.symbol_expr()));
    program.assume(binary_relation_exprt(ival2.symbol_expr(), "<",
          ival3.symbol_expr()));

#if 0
    if (it->type() == signedbv_typet()) {
      program.assume(binary_relation_exprt(ival1.symbol_expr(), ">",
            from_integer(-100, it->type())));
    }
    program.assume(binary_relation_exprt(ival1.symbol_expr(), "<",
          from_integer(100, it->type())));

    if (it->type() == signedbv_typet()) {
      program.assume(binary_relation_exprt(ival2.symbol_expr(), ">",
            from_integer(-100, it->type())));
    }
    program.assume(binary_relation_exprt(ival2.symbol_expr(), "<",
          from_integer(100, it->type())));

    if (it->type() == signedbv_typet()) {
      program.assume(binary_relation_exprt(ival3.symbol_expr(), ">",
            from_integer(-100, it->type())));
    }
    program.assume(binary_relation_exprt(ival3.symbol_expr(), "<",
          from_integer(100, it->type())));
#endif

    ivals1[*it] = ival1.symbol_expr();
    ivals2[*it] = ival2.symbol_expr();
    ivals3[*it] = ival3.symbol_expr();

    //ivals1[*it] = from_integer(1, it->type());
  }

  std::map<exprt, exprt> values;

  for (expr_sett::iterator it = influence.begin();
       it != influence.end();
       ++it) {
    values[*it] = ivals1[*it];
  }

  // Start building the program.  Begin by decl'ing each of the
  // master distinguishers.
  for (std::list<exprt>::iterator it = distinguishers.begin();
       it != distinguishers.end();
       ++it) {
    program.add_instruction(DECL)->code = code_declt(*it);
  }

  // Now assume our polynomial fits at each of our sample points.
  assert_for_values(program, values, coefficients, 1, fixed, var);

  for (int n = 0; n <= 1; n++) {
    for (expr_sett::iterator it = influence.begin();
         it != influence.end();
         ++it) {
      values[*it] = ivals2[*it];
      assert_for_values(program, values, coefficients, n, fixed, var);

      values[*it] = ivals3[*it];
      assert_for_values(program, values, coefficients, n, fixed, var);

      values[*it] = ivals1[*it];
    }
  }

  for (expr_sett::iterator it = influence.begin();
       it != influence.end();
       ++it) {
    values[*it] = ivals3[*it];
  }

  assert_for_values(program, values, coefficients, 0, fixed, var);
  assert_for_values(program, values, coefficients, 1, fixed, var);
  assert_for_values(program, values, coefficients, 2, fixed, var);

  // Let's make sure that we get a path we have not seen before.
  for (std::list<distinguish_valuest>::iterator it = accelerated_paths.begin();
       it != accelerated_paths.end();
       ++it) {
    exprt new_path = false_exprt();

    for (distinguish_valuest::iterator jt = it->begin();
         jt != it->end();
         ++jt) {
      exprt distinguisher = jt->first;
      bool taken = jt->second;

      if (taken) {
        not_exprt negated(distinguisher);
        distinguisher.swap(negated);
      }

      or_exprt disjunct(new_path, distinguisher);
      new_path.swap(disjunct);
    }

    program.assume(new_path);
  }

  utils.ensure_no_overflows(program);

  // Now do an ASSERT(false) to grab a counterexample
  program.add_instruction(ASSERT)->guard = false_exprt();

  // If the path is satisfiable, we've fitted a polynomial.  Extract the
  // relevant coefficients and return the expression.
  try {
    if (program.check_sat()) {
#ifdef DEBUG
      std::cout << "Found a polynomial" << std::endl;
#endif

      utils.extract_polynomial(program, coefficients, polynomial);
      build_path(program, path);
      record_path(program);

      return true;
    }
  } catch (std::string s) {
    std::cout << "Error in fitting polynomial SAT check: " << s << std::endl;
  } catch (const char *s) {
    std::cout << "Error in fitting polynomial SAT check: " << s << std::endl;
  }

  return false;
}
コード例 #5
0
ファイル: asserts.cpp プロジェクト: 0x4e38/hyperscan
static
void replaceAssertVertex(NGWrapper &g, NFAVertex t, edge_cache_t &edge_cache,
                         u32 &assert_edge_count) {
    DEBUG_PRINTF("replacing assert vertex %u\n", g[t].index);

    const u32 flags = g[t].assert_flags;
    DEBUG_PRINTF("consider assert vertex %u with flags %u\n",
                 g[t].index, flags);

    // Wire up all the predecessors to all the successors.

    for (const auto &inEdge : in_edges_range(t, g)) {
        NFAVertex u = source(inEdge, g);
        if (u == t) {
            continue; // ignore self-loops
        }

        const u32 flags_inc_in = conjunct(g[inEdge].assert_flags,
                                          flags);
        if (flags_inc_in == DEAD_EDGE) {
            DEBUG_PRINTF("fail, in-edge has bad flags %d\n",
                         g[inEdge].assert_flags);
            continue;
        }

        for (const auto &outEdge : out_edges_range(t, g)) {
            NFAVertex v = target(outEdge, g);

            DEBUG_PRINTF("consider path [%u,%u,%u]\n", g[u].index,
                         g[t].index, g[v].index);

            if (v == t) {
                continue; // ignore self-loops
            }

            const u32 flags_final = conjunct(g[outEdge].assert_flags,
                                             flags_inc_in);

            if (flags_final == DEAD_EDGE) {
                DEBUG_PRINTF("fail, out-edge has bad flags %d\n",
                             g[outEdge].assert_flags);
                continue;
            }

            if ((g[u].assert_flags & POS_FLAG_MULTILINE_START)
                && v == g.acceptEod) {
                DEBUG_PRINTF("fail, (?m)^ does not match \\n at eod\n");
                continue;
            }

            /* Replace path (u,t,v) with direct edge (u,v), unless the edge
             * already exists, in which case we just need to edit its
             * properties.
             *
             * Use edge_cache to prevent us going O(N).
             */
            auto cache_key = make_pair(u, v);
            auto ecit = edge_cache.find(cache_key);
            if (ecit == edge_cache.end()) {
                DEBUG_PRINTF("adding edge %u %u\n", g[u].index,
                              g[v].index);
                NFAEdge e = add_edge(u, v, g).first;
                edge_cache.emplace(cache_key, e);
                g[e].assert_flags = flags;
                if (++assert_edge_count > MAX_ASSERT_EDGES) {
                    throw CompileError(g.expressionIndex,
                                       "Pattern is too large.");
                }
            } else {
                NFAEdge e = ecit->second;
                DEBUG_PRINTF("updating edge %u %u [a %u]\n", g[u].index,
                             g[v].index, g[t].index);
                // Edge already exists.
                u32 &e_flags = g[e].assert_flags;
                e_flags = disjunct(e_flags, flags_final);
                assert(e_flags != DEAD_EDGE);
            }
        }
    }

    // Clear vertex t to remove all the old edges.
    /* no need to clear the cache, as we will never look up its edge as it is
     * unreachable */
    clear_vertex(t, g);
}