Beispiel #1
0
string
get_latex_style (tree t) {
  if (N(t) != 3 && N(t) != 2) return "";
  string s= trim_spaces (string_arg (t[N(t)-1]));
  string opt= N(t)==3? trim_spaces (string_arg (t[1])): string ("");
  array<string> opts= trim_spaces (tokenize (opt, ","));
  if (N(t) == 3 && occurs ("acmart", s)) {
    if (occurs ("acmsmall", opt)) return "acmsmall";
  }
  if (N(t) == 3 && occurs ("revtex", s)) {
    if (contains (string ("aip"), opts)) return "aip";
    if (contains (string ("aps"), opts)) return "aps";
  }
  if (occurs ("llncs", s))
    return "llncs";
  if (occurs ("svjour", s))
    return "svjour";
  if (occurs ("ifacconf", s))
    return "ifac";
  if (occurs ("IEEEconf", s))
    return "ieeeconf";
  if (occurs ("IEEEtran", s))
    return "ieeetran";
  if (occurs ("acm_proc", s))
    return "acmconf";
  if (occurs ("sig-alt", s))
    return "sig-alternate";
  return s;
}
Beispiel #2
0
static void
init_main_paths () {
#ifdef __MINGW32__
  if (is_none (get_env_path ("TEXMACS_HOME_PATH", get_env ("APPDATA") * "/TeXmacs"))) {
#else
  if (is_none (get_env_path ("TEXMACS_HOME_PATH", "~/.TeXmacs"))) {
#endif
    boot_error << "\n";
    boot_error << "Installation problem: please send a bug report.\n";
    boot_error << "'TEXMACS_HOME_PATH' could not be set to '~/.TeXmacs'.\n";
    boot_error << "You may try to set this environment variable manually\n";
    boot_error << "\n";
    FAILED ("installation problem");
    exit (1);
  }
}

/******************************************************************************
* Directory for temporary files
******************************************************************************/

static string main_tmp_dir= "$TEXMACS_HOME_PATH/system/tmp";

static void
make_dir (url which) {
  if (!is_directory (which)) {
    make_dir (head (which));
    mkdir (which);
  }
}

static url
url_temp_dir_sub () {
#ifdef __MINGW32__
  static url tmp_dir=
    url_system (main_tmp_dir) * url_system (as_string (time (NULL)));
#else
  static url tmp_dir=
    url_system (main_tmp_dir) * url_system (as_string ((int) getpid ()));
#endif
  return (tmp_dir);
}

url
url_temp_dir () {
  static url u;
  if (u == url_none()) {
    u= url_temp_dir_sub ();
    make_dir (u);
  }
  return u;
}

bool
process_running (int pid) {
  string cmd= "ps -p " * as_string (pid);
  string ret= eval_system (cmd);
  return occurs ("texmacs", ret) && occurs (as_string (pid), ret);
}
// This method was adapted from the definition of function
// void convertInt64ToAscii(const Int64 &src, char* tgt)
// defined in w:/common/Int64.cpp
void ComUID::convertTo19BytesFixedWidthStringWithZeroesPrefix (ComString &tgt) const
{
  Int64 temp = get_value();
  char buffer[20];
  char *s = &buffer[occurs(buffer) - 1];
  memset(buffer, '0', occurs(buffer) - 1);
  *s = '\0';
  do {
    unsigned char c = (unsigned char) (temp % 10);
    *--s = (char)(c + '0');
    temp /= 10;
  } while (temp != 0);
  tgt = buffer;
}
Beispiel #4
0
inline order::result lpo::compare_core(expr_offset s, expr_offset t, unsigned depth) {
    s = find(s);
    t = find(t);
    
    if (max_depth(depth))
        return UNKNOWN;

    if (is_var(s.get_expr()))
        return s == t ? EQUAL : UNCOMPARABLE;
    else if (is_var(t.get_expr()))
        return occurs(t, s) ? GREATER : UNCOMPARABLE;
    else {
        func_decl * f = to_app(s.get_expr())->get_decl();
        func_decl * g = to_app(t.get_expr())->get_decl();
        if (f_greater(f, g))
            return dominates_args(s, t, depth) ? GREATER : NOT_GTEQ;
        else if (f != g)
            return arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ;
        else {
            result r = lex_compare(s, t, depth);
            if (r == GREATER) {
                if (dominates_args(s, t, depth))
                    return GREATER;
            }
            else if (r == EQUAL)
                return EQUAL;
            return to_app(s.get_expr())->get_num_args() > 1 && arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ;
        }
    }
}
Beispiel #5
0
 bool solve_arith_core(app * lhs, expr * rhs, expr * eq, app_ref & var, expr_ref & def, proof_ref & pr) {
     SASSERT(m_a_util.is_add(lhs));
     bool is_int  = m_a_util.is_int(lhs);
     expr * a = nullptr; 
     expr * v = nullptr;
     rational a_val;
     unsigned num = lhs->get_num_args();
     unsigned i;
     for (i = 0; i < num; i++) {
         expr * arg = lhs->get_arg(i);
         if (is_uninterp_const(arg) && !m_candidate_vars.is_marked(arg) && check_occs(arg) && !occurs(arg, rhs) && !occurs_except(arg, lhs, i)) {
             a_val = rational(1); 
             v     = arg;
             break;
         }
         else if (m_a_util.is_mul(arg, a, v) && 
                  is_uninterp_const(v) && 
                  !m_candidate_vars.is_marked(v) &&
                  m_a_util.is_numeral(a, a_val) &&
                  !a_val.is_zero() &&
                  (!is_int || a_val.is_minus_one()) &&
                  check_occs(v) &&
                  !occurs(v, rhs) && 
                  !occurs_except(v, lhs, i)) {
             break;
         }
     }
     if (i == num)
         return false;
     var = to_app(v);
     expr_ref inv_a(m());
     if (!a_val.is_one()) {
         inv_a = m_a_util.mk_numeral(rational(1)/a_val, is_int);
         rhs   = m_a_util.mk_mul(inv_a, rhs);
     }
     
     ptr_buffer<expr> other_args;
     for (unsigned j = 0; j < num; j++) {
         if (i != j) {
             if (inv_a)
                 other_args.push_back(m_a_util.mk_mul(inv_a, lhs->get_arg(j)));
             else
                 other_args.push_back(lhs->get_arg(j));
         }
     }
     switch (other_args.size()) {
     case 0:
         def = rhs;
         break;
     case 1:
         def = m_a_util.mk_sub(rhs, other_args[0]);
         break;
     default:
         def = m_a_util.mk_sub(rhs, m_a_util.mk_add(other_args.size(), other_args.c_ptr()));
         break;
     }
     if (m_produce_proofs)
         pr = m().mk_rewrite(eq, m().mk_eq(var, def));
     return true;
 }
void CmGetMVOperatorTypeAsLit (const OperatorTypeEnum e, char * l)
{
  NABoolean found;
  enumToLiteral (OperatorTypeXlateArray, occurs(OperatorTypeXlateArray), e, l, found);
  if (!found)
    strcpy (l, COM_UNKNOWN_AGG_LIT);
}
Beispiel #7
0
 // (ite c (= x t1) (= x t2)) --> (= x (ite c t1 t2))
 bool solve_ite_core(app * ite, expr * lhs1, expr * rhs1, expr * lhs2, expr * rhs2, app_ref & var, expr_ref & def, proof_ref & pr) {
     if (lhs1 != lhs2)
         return false;
     if (!is_uninterp_const(lhs1) || m_candidate_vars.is_marked(lhs1))
         return false;
     if (occurs(lhs1, ite->get_arg(0)) || occurs(lhs1, rhs1) || occurs(lhs1, rhs2))
         return false;
     if (!check_occs(lhs1))
         return false;
     var = to_app(lhs1);
     def = m().mk_ite(ite->get_arg(0), rhs1, rhs2);
     
     if (m_produce_proofs)
         pr = m().mk_rewrite(ite, m().mk_eq(var, def));
     return true;
 }
//----------------------------------------------------------------------
//
// Query Invalidation Action type translations
//
void ComQIActionTypeEnumToLiteral (const ComQIActionType qiType,
                             char* qiTypeLiteral)
{
  NABoolean found;
  enumToLiteral ( qiTypeConversionTable, occurs(qiTypeConversionTable), qiType, qiTypeLiteral, found);

  ComASSERT (found);
}
Beispiel #9
0
 /**
    \brief Given t of the form (f s_0 ... s_n), 
    return true if x occurs in some s_j for j != i 
 */
 bool occurs_except(expr * x, app * t, unsigned i) {
     unsigned num = t->get_num_args();
     for (unsigned j = 0; j < num; j++) {
         if (i != j && occurs(x, t->get_arg(j)))
             return true;
     }
     return false;
 }
Beispiel #10
0
/*
 *super_block::add_block() --- add cfg node to cfg node list(cnl).
 */
void super_block::add_block(cfg_node * the_block) {
	if (the_block == NULL)
		fprintf(stderr, "add a NULL block\n");

	//If the block doesn't belong to nodes()
	if (!occurs(the_block, nodes())) {
		cnl->append(the_block);
	}
}
ComQIActionType ComQIActionTypeLiteralToEnum (const char * qiTypeLiteral)
{
  NABoolean found;
  ComQIActionType result =
          (ComQIActionType) literalToEnum (qiTypeConversionTable, occurs(qiTypeConversionTable), qiTypeLiteral, found);
  ComASSERT (found);

  return result;
}
Beispiel #12
0
rubber_stix_font_rep::rubber_stix_font_rep (string name, font base2):
  font_rep (name, base2), base (base2)
{
  this->copy_math_pars (base);
  dpi= (72 * base->wpt + (PIXEL/2)) / PIXEL;
  reg= !occurs ("-bold-", base->res_name);
  for (int i=0; i<18; i++) {
    initialized << false;
    subfn << base;
  }
}
Beispiel #13
0
/*
 *super_block::last_block() --- return the last block of the super block
 */
cfg_node *super_block::last_block() {
	cfg_node *last = NULL;
	cfg_node_list_iter full_cnl_iter(the_full_cnl);
	while (!full_cnl_iter.is_empty()) {
		cfg_node *test = full_cnl_iter.step();
		if (occurs(test, nodes())) {
			last = test;
		}
	}
	return last;
}
// *****************************************************************************
// *                                                                           *
// * Function: PrivMgr::ObjectEnumToLit                                        *
// *                                                                           *
// *    Returns the two character literal associated with the object type enum.*
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <objectType>                    ComObjectType                   In       *
// *    is the object type enum.                                               *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// * Returns: const char                                                       *
// *                                                                           *
// *****************************************************************************
const char * PrivMgr::ObjectEnumToLit(ComObjectType objectType)

{

   for (size_t i = 0; i < occurs(objectTypeConversionTable); i++)
      if (objectType == objectTypeConversionTable[i].enum_)
         return objectTypeConversionTable[i].literal_;

   return COM_UNKNOWN_OBJECT_LIT;  
    
}
Beispiel #15
0
        bool trivial_solve1(expr * lhs, expr * rhs, app_ref & var, expr_ref & def, proof_ref & pr) { 

            if (is_uninterp_const(lhs) && !m_candidate_vars.is_marked(lhs) && !occurs(lhs, rhs) && check_occs(lhs)) {
                var = to_app(lhs); 
                def = rhs;
                pr  = nullptr;
                return true;
            }
            else {
                return false;
            }
        }
Beispiel #16
0
bool is_ceqv(tmp_type_context & tctx, expr e) {
    if (has_expr_metavar(e))
        return false;
    name_set to_find;
    // Define a procedure for removing arguments from to_find.
    auto visitor_fn = [&](expr const & e, unsigned) {
        if (is_local(e)) {
            to_find.erase(mlocal_name(e));
            return false;
        } else if (is_metavar(e)) {
            return false;
        } else {
            return true;
        }
    };
    environment const & env = tctx.env();
    bool is_std = is_standard(env);
    buffer<expr> hypotheses; // arguments that are propositions
    while (is_pi(e)) {
        if (!to_find.empty()) {
            // Support for dependent types.
            // We may find the instantiation for the previous arguments
            // by matching the type.
            for_each(binding_domain(e), visitor_fn);
        }
        expr local = tctx.mk_tmp_local(binding_domain(e));
        if (binding_info(e).is_inst_implicit()) {
            // If the argument can be instantiated by type class resolution, then
            // we don't need to find it in the lhs
        } else if (is_std && tctx.is_prop(binding_domain(e))) {
            // If the argument is a proposition, we store it in hypotheses.
            // We check whether the lhs occurs in hypotheses or not.
            hypotheses.push_back(binding_domain(e));
        } else {
            to_find.insert(mlocal_name(local));
        }
        e = instantiate(binding_body(e), local);
    }
    expr lhs, rhs;
    if (!is_simp_relation(env, e, lhs, rhs))
        return false;
    // traverse lhs, and remove found variables from to_find
    for_each(lhs, visitor_fn);
    if (!to_find.empty())
        return false;
    // basic looping ceq detection: the left-hand-side should not occur in the right-hand-side,
    // nor it should occur in any of the hypothesis
    if (occurs(lhs, rhs))
        return false;
    if (std::any_of(hypotheses.begin(), hypotheses.end(), [&](expr const & h) { return occurs(lhs, h); }))
        return false;
    return true;
}
Beispiel #17
0
 bool isolate_var(app* arg, app_ref& var, expr_ref& div, unsigned i, app* lhs, expr* rhs) {
     if (!m_a_util.is_mul(arg)) return false;
     unsigned n = arg->get_num_args();
     for (unsigned j = 0; j < n; ++j) {
         expr* e = arg->get_arg(j);
         bool ok = is_uninterp_const(e) && check_occs(e) && !occurs(e, rhs) && !occurs_except(e, lhs, i);
         if (!ok) continue;
         var = to_app(e);
         for (unsigned k = 0; ok && k < n; ++k) {
             expr* arg_k = arg->get_arg(k);
             ok = k == j || (!occurs(var, arg_k) && is_nonzero(arg_k));
         }
         if (!ok) continue;
         ptr_vector<expr> args;
         for (unsigned k = 0; k < n; ++k) {
             if (k != j) args.push_back(arg->get_arg(k));
         }
         div = m_a_util.mk_mul(args.size(), args.c_ptr());
         return true;
     }
     return false;
 }
void unifier::operator()(const type_operator& x, const type_variable& y)
{
    if(occurs(x, y))
        throw recursive_unification(y, x);

    /*for(const auto& i : x) {
        type ty = type(y);
        type ti = type(i);
        boost::apply_visitor(*this, ty, ti);
    }*/

    eliminate(y, x);
}
// *****************************************************************************
// *                                                                           *
// * Function: PrivMgr::ObjectLitToEnum                                        *
// *                                                                           *
// *    Returns the enum associated with the object type literal.              *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <objectType>                    ComObjectType                   In       *
// *    is the object type enum.                                               *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// * Returns: ComObjectType                                                    *
// *                                                                           *
// *****************************************************************************
ComObjectType PrivMgr::ObjectLitToEnum(const char *objectLiteral)

{

   for (size_t i = 0; i < occurs(objectTypeConversionTable); i++)
   {
      const literalAndEnumStruct & elem = objectTypeConversionTable[i];
      if (!strncmp(elem.literal_,objectLiteral,2))
         return static_cast<ComObjectType>(elem.enum_);
   }
   
   return COM_UNKNOWN_OBJECT;
   
}
Beispiel #20
0
static url
url_get_atom (string s, int type) {
  if (type < URL_STANDARD) {
    if (s == "~") return url_system (get_env ("HOME"));
    if (starts (s, "$")) {
      string val= get_env (s (1, N(s)));
      if (val == "") return url_none ();
      return unblank (url_system (val));
    }
  }
  if (occurs ("*", s)) return url_wildcard (s);
#ifdef WINPATHS
  if(N(s)==2 && ends (s, ":")) s->resize(1);	// remove the ':' after unit letter
#endif
  return as_url (tree (s));
}
Beispiel #21
0
/**
   \brief Return true if n contains f. The method ignores the sub-expression \c exception.

   \remark n is a "polynomial".
*/
bool macro_util::poly_contains_head(expr * n, func_decl * f, expr * exception) const {
    unsigned num_args;
    expr * const * args;
    if (is_add(n)) {
        num_args = to_app(n)->get_num_args();
        args     = to_app(n)->get_args();
    }
    else {
        num_args = 1;
        args     = &n;
    }
    for (unsigned i = 0; i < num_args; i++) {
        expr * arg = args[i];
        if (arg != exception && occurs(f, arg))
            return true;
    }
    return false;
}
Beispiel #22
0
/*
 * Common IPC sending-receiving routine
 */
void
srvSendReceive(void)
{
	if(sendRequest(&ipc_packet_data) < 0)
		ipcerror("microsh::srvSendReceive():sendRequest() - failed");
	else
	{
		int nbytes = 0;
		int n = 0;

		sleep(1); /* yet another nasty kludge */
		          /* looks like we need semaphores again? */
/*		do
*/		{
			ipc_packet_data.reqresp = &response;
			nbytes = receiveResponse(&ipc_packet_data);

			PRINT("nbytes=%d\n", nbytes);

			if(nbytes < 0)
			{
				ipcerror("microsh::srvSendReceive():receiveResponse() - failed");
				/*break;*/
			}
			else
			{
				PRINT("Server's [%d] Response: ", response.srv_pid);
				printf("%s", response.data); fflush(stdout);
				PRINT("\n");
			}

		} /*while(nbytes && n++ != 1);*/

		PRINT("DONE Send/Receive\n");

		if(occurs(response.data, "exit") == 0)
		{
			printf("Exit has been received. Resetting...\n");
			finishIPC(&ipc_packet_data);
			status.connected = false;
			reset();
		}
	}
}
Beispiel #23
0
/**
    \brief Given a sequence metas: <tt>(?m_1 ...) (?m_2 ... ) ... (?m_k ...)</tt>,
    we say ?m_i is "redundant" if it occurs in the type of some ?m_j.
    This procedure removes from metas any redundant element.
*/
static void remove_redundant_metas(buffer<expr> & metas) {
    buffer<expr> mvars;
    for (expr const & m : metas)
        mvars.push_back(get_app_fn(m));
    unsigned k = 0;
    for (unsigned i = 0; i < metas.size(); i++) {
        bool found = false;
        for (unsigned j = 0; j < metas.size(); j++) {
            if (j != i) {
                if (occurs(mvars[i], mlocal_type(mvars[j]))) {
                    found = true;
                    break;
                }
            }
        }
        if (!found) {
            metas[k] = metas[i];
            k++;
        }
    }
    metas.shrink(k);
}
Beispiel #24
0
/*
 *	Does type1 occur as a proper sub-type of type2?
 *	(both are dereferenced.)
 */
local Bool
occurs(Cell *type1, Cell *type2)
{
	Cell	*arg;
	Cell	*type;

	if (type2->c_class == C_TCONS) {
		/* mark it in case we encounter it recursively */
		type2->c_class = C_VISITED;
		for (arg = type2->c_abbr->c_targ;
		     arg != NOCELL;
		     arg = arg->c_tail) {
			ASSERT( arg->c_class == C_TLIST );
			type = deref(arg->c_head);
			if (type1 == type || occurs(type1, type)) {
				type2->c_class = C_TCONS;
				return TRUE;
			}
		}
		type2->c_class = C_TCONS;
	}
	return FALSE;
}
Beispiel #25
0
 void run(UniformRandomNumberGenerator f, Counter & count, int n) const
 {
   typedef typename UniformRandomNumberGenerator::result_type result_type;
   assert(std::numeric_limits<result_type>::is_integer);
   assert(f.min() == 0);
   assert(f.max() == static_cast<result_type>(d-1));
   std::vector<bool> occurs(d);
   for(int i = 0; i < n; ++i) {
     occurs.assign(d, false);
     unsigned int r = 0;            // length of current sequence
     int q = 0;                     // number of non-duplicates in current set
     for(;;) {
       result_type val = f();
       ++r;
       if(!occurs[val]) {       // new set element
         occurs[val] = true;
         ++q;
         if(q == d)
           break;     // one complete set
       }
     }
     count(std::min(r-d, classes()-1));
   }
 }
OperatorTypeEnum CmGetMVOperatorTypeEnum (const char * l)
{
  NABoolean found;
  OperatorTypeEnum result = (OperatorTypeEnum) literalToEnum (OperatorTypeXlateArray, occurs(OperatorTypeXlateArray), l, found);
  if (!found)
    result = ITM_IS_UNKNOWN;
  return result;
}
Beispiel #27
0
/**
   \brief Return true if n is of the form
   
   (= t (f x_{k_1}, ..., x_{k_n}))    OR
   (iff t (f x_{k_1}, ..., x_{k_n}))

   where
   
   is_macro_head((f x_{k_1}, ..., x_{k_n})) returns true   AND
   t does not contain f                                    AND
   f is not in forbidden_set

   In case of success
   head will contain (f x_{k_1}, ..., x_{k_n}) AND
   def  will contain t

*/
bool macro_util::is_right_simple_macro(expr * n, unsigned num_decls, app * & head, expr * & def) const {
    if (m_manager.is_eq(n) || m_manager.is_iff(n)) {
        expr * lhs = to_app(n)->get_arg(0);
        expr * rhs = to_app(n)->get_arg(1);
        if (is_macro_head(rhs, num_decls) && !is_forbidden(to_app(rhs)->get_decl()) && !occurs(to_app(rhs)->get_decl(), lhs)) {
            head = to_app(rhs);
            def  = lhs;
            return true;
        }
    }
    return false;
}
Beispiel #28
0
/*
 *	Print a type.
 *	The occurs check for mu-types makes this quadratic, but I can't
 *	think of anything better (and maybe it's not too bad).
 */
local void
pr_c_ty_value(FILE *f, Cell *type, int context)
{
	Op	*op;
	int	prec;
	Bool	is_mu;
	DefType	*tcons;
	Cell	*targ;

	type = deref(type);
	is_mu = type->c_class == C_VOID || occurs(type, type);
	prec = is_mu ? PREC_MU : n_ty_precedence(type);

	if (prec < context)
		(void)fprintf(f, "(");

	if (is_mu) {
		var_count++;
		type->c_varno = var_count;
		(void)fprintf(f, "%s ", n_mu);
		tv_print(f, (Natural)(type->c_varno - 1));
		(void)fprintf(f, " %s ", n_gives);
	}

	switch (type->c_class) {
	case C_TVAR:
		if (type->c_varno == 0) {
			var_count++;
			type->c_varno = var_count;
		}
		tv_print(f, (Natural)(type->c_varno - 1));
	when C_VOID:
		tv_print(f, (Natural)(type->c_varno - 1));
	when C_TCONS:
		ASSERT( type->c_abbr->c_class == C_TSUB );
		tcons = type->c_abbr->c_tcons;
		targ = type->c_abbr->c_targ;
		ASSERT( tcons->dt_arity == 0 || targ->c_class == C_TLIST );
		/* mark it as a VAR in case we encounter it recursively */
		type->c_class = C_TVAR;
		if (tcons->dt_arity == 2 && tcons->dt_tupled &&
		    (op = op_lookup(tcons->dt_name)) != NULL) {
						/* infix */
			pr_c_ty_value(f, targ->c_head, LeftPrec(op));
			(void)fprintf(f, " %s ", tcons->dt_name);
			pr_c_ty_value(f, targ->c_tail->c_head, RightPrec(op));
		} else if (tcons->dt_tupled) {
			(void)fprintf(f, "%s (", tcons->dt_name);
			pr_c_ty_value(f, targ->c_head, PREC_BODY);
			for (targ = targ->c_head;
			     targ != NOCELL;
			     targ = targ->c_tail) {
				ASSERT( targ->c_class == C_TLIST );
				(void)fprintf(f, ", ");
				pr_c_ty_value(f, targ->c_head, PREC_BODY);
			}
			(void)fprintf(f, ")");
		} else {
			(void)fprintf(f, "%s", tcons->dt_name);
			for ( ; targ != NOCELL; targ = targ->c_tail) {
				ASSERT( targ->c_class == C_TLIST );
				(void)fprintf(f, " ");
				pr_c_ty_value(f, targ->c_head, PREC_ARG);
			}
		}
		type->c_class = C_TCONS;
	otherwise:
		NOT_REACHED;
	}

	if (prec < context)
		(void)fprintf(f, ")");
}
Beispiel #29
0
vm_obj level_occurs(vm_obj const & o1, vm_obj const & o2) {
    return mk_vm_bool(occurs(to_level(o1), to_level(o2)));
}