Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c, Z3_bool is_forall, unsigned weight, Z3_symbol quantifier_id, Z3_symbol skolem_id, unsigned num_bound, Z3_app const bound[], unsigned num_patterns, Z3_pattern const patterns[], unsigned num_no_patterns, Z3_ast const no_patterns[], Z3_ast body) { Z3_TRY; LOG_Z3_mk_quantifier_const_ex(c, is_forall, weight, quantifier_id, skolem_id, num_bound, bound, num_patterns, patterns, num_no_patterns, no_patterns, body); RESET_ERROR_CODE(); svector<Z3_symbol> names; svector<Z3_sort> types; ptr_vector<expr> bound_asts; if (num_patterns > 0 && num_no_patterns > 0) { SET_ERROR_CODE(Z3_INVALID_USAGE); RETURN_Z3(0); } if (num_bound == 0) { SET_ERROR_CODE(Z3_INVALID_USAGE); RETURN_Z3(0); } for (unsigned i = 0; i < num_bound; ++i) { app* a = to_app(bound[i]); if (a->get_kind() != AST_APP) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } symbol s(to_app(a)->get_decl()->get_name()); names.push_back(of_symbol(s)); types.push_back(of_sort(mk_c(c)->m().get_sort(a))); bound_asts.push_back(a); if (a->get_family_id() != null_family_id || a->get_num_args() != 0) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } } // Abstract patterns svector<Z3_pattern> _patterns; expr_ref_vector pinned(mk_c(c)->m()); for (unsigned i = 0; i < num_patterns; ++i) { expr_ref result(mk_c(c)->m()); app* pat = to_pattern(patterns[i]); SASSERT(mk_c(c)->m().is_pattern(pat)); expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result); SASSERT(result.get()->get_kind() == AST_APP); pinned.push_back(result.get()); SASSERT(mk_c(c)->m().is_pattern(result.get())); _patterns.push_back(of_pattern(result.get())); } svector<Z3_ast> _no_patterns; for (unsigned i = 0; i < num_no_patterns; ++i) { expr_ref result(mk_c(c)->m()); if (!is_app(to_expr(no_patterns[i]))) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } app* pat = to_app(to_expr(no_patterns[i])); expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result); SASSERT(result.get()->get_kind() == AST_APP); pinned.push_back(result.get()); _no_patterns.push_back(of_ast(result.get())); } expr_ref abs_body(mk_c(c)->m()); expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), to_expr(body), abs_body); Z3_ast result = mk_quantifier_ex_core(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, _patterns.c_ptr(), num_no_patterns, _no_patterns.c_ptr(), names.size(), types.c_ptr(), names.c_ptr(), of_ast(abs_body.get())); RETURN_Z3(result); Z3_CATCH_RETURN(0); }
static void is_sorted(svector<unsigned> const& v) { for (unsigned i = 0; i + 1 < v.size(); ++i) { SASSERT(v[i] <= v[i+1]); } }
virtual void operator()(goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { bool models_enabled = in->models_enabled(); bool proofs_enabled = in->proofs_enabled(); bool cores_enabled = in->unsat_core_enabled(); ast_manager & m = in->m(); goal_ref_buffer r1; model_converter_ref mc1; proof_converter_ref pc1; expr_dependency_ref core1(m); result.reset(); mc = 0; pc = 0; core = 0; m_t1->operator()(in, r1, mc1, pc1, core1); SASSERT(!is_decided(r1) || (!pc1 && !core1)); // the pc and core of decided goals is 0 unsigned r1_size = r1.size(); SASSERT(r1_size > 0); checkpoint(); if (r1_size == 1) { if (r1[0]->is_decided()) { result.push_back(r1[0]); if (models_enabled) mc = mc1; SASSERT(!pc); SASSERT(!core); return; } goal_ref r1_0 = r1[0]; m_t2->operator()(r1_0, result, mc, pc, core); if (models_enabled) mc = concat(mc1.get(), mc.get()); if (proofs_enabled) pc = concat(pc1.get(), pc.get()); if (cores_enabled) core = m.mk_join(core1.get(), core); } else { if (cores_enabled) core = core1; proof_converter_ref_buffer pc_buffer; model_converter_ref_buffer mc_buffer; sbuffer<unsigned> sz_buffer; goal_ref_buffer r2; for (unsigned i = 0; i < r1_size; i++) { checkpoint(); goal_ref g = r1[i]; r2.reset(); model_converter_ref mc2; proof_converter_ref pc2; expr_dependency_ref core2(m); m_t2->operator()(g, r2, mc2, pc2, core2); if (is_decided(r2)) { SASSERT(r2.size() == 1); if (is_decided_sat(r2)) { // found solution... result.push_back(r2[0]); if (models_enabled) { // mc2 contains the actual model model_ref md; md = alloc(model, m); apply(mc2, md, 0); apply(mc1, md, i); mc = model2model_converter(md.get()); } SASSERT(!pc); SASSERT(!core); return; } else { SASSERT(is_decided_unsat(r2)); // the proof and unsat core of a decided_unsat goal are stored in the node itself. // pc2 and core2 must be 0. SASSERT(!pc2); SASSERT(!core2); if (models_enabled) mc_buffer.push_back(0); if (proofs_enabled) pc_buffer.push_back(proof2proof_converter(m, r2[0]->pr(0))); if (models_enabled || proofs_enabled) sz_buffer.push_back(0); if (cores_enabled) core = m.mk_join(core.get(), r2[0]->dep(0)); } } else { result.append(r2.size(), r2.c_ptr()); if (models_enabled) mc_buffer.push_back(mc2.get()); if (proofs_enabled) pc_buffer.push_back(pc2.get()); if (models_enabled || proofs_enabled) sz_buffer.push_back(r2.size()); if (cores_enabled) core = m.mk_join(core.get(), core2.get()); } } if (result.empty()) { // all subgoals were shown to be unsat. // create an decided_unsat goal with the proof in->reset_all(); proof_ref pr(m); if (proofs_enabled) apply(m, pc1, pc_buffer, pr); SASSERT(cores_enabled || core == 0); in->assert_expr(m.mk_false(), pr, core); core = 0; result.push_back(in.get()); SASSERT(!mc); SASSERT(!pc); SASSERT(!core); } else { if (models_enabled) mc = concat(mc1.get(), mc_buffer.size(), mc_buffer.c_ptr(), sz_buffer.c_ptr()); if (proofs_enabled) pc = concat(pc1.get(), pc_buffer.size(), pc_buffer.c_ptr(), sz_buffer.c_ptr()); SASSERT(cores_enabled || core == 0); } } }
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int /*nCmdShow*/) { HRESULT hRes = OleInitialize(NULL); SASSERT(SUCCEEDED(hRes)); int nRet = 0; SComMgr *pComMgr = new SComMgr(_T("imgdecoder-gdip")); { BOOL bLoaded=FALSE; CAutoRefPtr<SOUI::IImgDecoderFactory> pImgDecoderFactory; CAutoRefPtr<SOUI::IRenderFactory> pRenderFactory; bLoaded = pComMgr->CreateRender_GDI((IObjRef**)&pRenderFactory); SASSERT_FMT(bLoaded,_T("load interface [render] failed!")); bLoaded=pComMgr->CreateImgDecoder((IObjRef**)&pImgDecoderFactory); SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("imgdecoder")); pRenderFactory->SetImgDecoderFactory(pImgDecoderFactory); SApplication *theApp = new SApplication(pRenderFactory, hInstance); theApp->RegisterWndFactory(TplSWindowFactory<SEdit2>()); theApp->RegisterWndFactory(TplSWindowFactory<SImgCanvas>()); theApp->RegisterWndFactory(TplSWindowFactory<SFolderTreeList>()); HMODULE hSysResource=LoadLibrary(SYS_NAMED_RESOURCE); if(hSysResource) { CAutoRefPtr<IResProvider> sysSesProvider; CreateResProvider(RES_PE,(IObjRef**)&sysSesProvider); sysSesProvider->Init((WPARAM)hSysResource,0); theApp->LoadSystemNamedResource(sysSesProvider); } CAutoRefPtr<IResProvider> pResProvider; #if (RES_TYPE == 0) //将程序的运行路径修改到项目所在目录所在的目录 SStringT strPath = theApp->GetAppDir(); strPath += _T("\\..\\demos\\SoTool"); SetCurrentDirectory(strPath); CreateResProvider(RES_FILE, (IObjRef**)&pResProvider); if (!pResProvider->Init((LPARAM)_T("uires"), 0)) { SASSERT(0); return 1; } #else CreateResProvider(RES_PE, (IObjRef**)&pResProvider); pResProvider->Init((WPARAM)hInstance, 0); #endif theApp->AddResProvider(pResProvider); // BLOCK: Run application { CMainDlg dlgMain; dlgMain.Create(GetActiveWindow()); dlgMain.SendMessage(WM_INITDIALOG); dlgMain.CenterWindow(dlgMain.m_hWnd); dlgMain.ShowWindow(SW_SHOWNORMAL); nRet = theApp->Run(dlgMain.m_hWnd); } delete theApp; } delete pComMgr; OleUninitialize(); return nRet; }
datatype_decl_plugin::~datatype_decl_plugin() { SASSERT(m_util.get() == 0); }
void object::dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) m_context.del_object(this); }
zstring zstring::operator+(zstring const& other) const { SASSERT(m_encoding == other.m_encoding); zstring result(*this); result.m_buffer.append(other.m_buffer); return result; }
static void add_some_facts(imdd_manager & m, imdd_ref & d, bool destructive = false, bool memoize = true) { std::cout << "destructive: " << destructive << ", memoize: " << memoize << std::endl; add_triple(m, d, 1, 10, 3, 3, 0, 100, destructive, memoize); std::cout << mk_ll_pp(d, m) << std::endl; SASSERT(m.contains(d, 2, 3, 20)); SASSERT(!m.contains(d, 2, 4, 20)); SASSERT(!m.contains(d, 2, 3, 200)); SASSERT(!m.contains(d, 0, 3, 200)); SASSERT(m.contains(d,1,3,0)); add_triple(m, d, 3, 6, 3, 4, 7, 101, destructive, memoize); std::cout << mk_ll_pp(d, m) << std::endl; add_triple(m, d, 3, 6, 2, 2, 7, 101, destructive, memoize); std::cout << mk_ll_pp(d, m) << std::endl; add_triple(m, d, 3, 6, 5, 6, 7, 101, destructive, memoize); SASSERT(m.contains(d, 2, 3, 20)); std::cout << mk_ll_pp(d, m) << std::endl; SASSERT(!m.contains(d, 2, 4, 20)); SASSERT(m.contains(d, 3, 4, 20)); SASSERT(!m.contains(d, 2, 3, 200)); SASSERT(!m.contains(d, 0, 3, 200)); SASSERT(m.contains(d,1,3,0)); }
void float_decl_plugin::del(parameter const & p) { SASSERT(p.is_external()); recycled_id(p.get_ext_id()); }
static void test_bound_relation() { std::cout << "bound relation\n"; smt_params params; ast_manager ast_m; register_engine re; context ctx(ast_m, re, params); arith_util autil(ast_m); relation_manager & m = ctx.get_rel_context()->get_rmanager(); m.register_plugin(alloc(bound_relation_plugin, m)); bound_relation_plugin& br = dynamic_cast<bound_relation_plugin&>(*m.get_relation_plugin(symbol("bound_relation"))); SASSERT(&br); relation_signature sig; sort* int_sort = autil.mk_int(); sig.push_back(int_sort); sig.push_back(int_sort); sig.push_back(int_sort); sig.push_back(int_sort); bound_relation& i1 = dynamic_cast<bound_relation&>(*br.mk_empty(sig)); bound_relation& i2 = dynamic_cast<bound_relation&>(*br.mk_full(0, sig)); i1.display(std::cout << "empty:\n"); i2.display(std::cout << "full:\n"); SASSERT(i1.empty()); SASSERT(!i2.empty()); app_ref cond1(ast_m), cond2(ast_m), cond3(ast_m); app_ref cond4(ast_m), cond5(ast_m), cond6(ast_m); app_ref num1(ast_m); cond1 = autil.mk_lt(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true)); cond2 = autil.mk_lt(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(1), true)); cond3 = autil.mk_lt(ast_m.mk_var(2, int_sort), ast_m.mk_var(3, int_sort)); cond4 = autil.mk_ge(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true)); cond5 = autil.mk_ge(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(0), true)); cond6 = autil.mk_ge(ast_m.mk_var(2, int_sort), autil.mk_numeral(rational(5), true)); app_ref lt_x0x1(ast_m), lt_x1x2(ast_m), lt_x0x3(ast_m), lt_x0x2(ast_m); lt_x0x1 = autil.mk_lt(ast_m.mk_var(0, int_sort), ast_m.mk_var(1, int_sort)); lt_x1x2 = autil.mk_lt(ast_m.mk_var(1, int_sort), ast_m.mk_var(2, int_sort)); lt_x0x2 = autil.mk_lt(ast_m.mk_var(0, int_sort), ast_m.mk_var(2, int_sort)); lt_x0x3 = autil.mk_lt(ast_m.mk_var(0, int_sort), ast_m.mk_var(3, int_sort)); num1 = autil.mk_numeral(rational(4), true); unsigned cols1[2] = { 1, 2}; unsigned cols2[2] = { 2, 3}; unsigned cols3[3] = { 0, 2, 3 }; relation_join_fn* join1 = br.mk_join_fn(i1, i2, 2, cols1, cols2); relation_transformer_fn* proj1 = br.mk_project_fn(i1, 2, cols2); relation_transformer_fn* ren1 = br.mk_rename_fn(i1, 3, cols3); relation_union_fn* union1 = br.mk_union_fn(i1, i2, &i1); relation_mutator_fn* filterId1 = br.mk_filter_identical_fn(i1, 2, cols1); relation_mutator_fn* filterEq1 = br.mk_filter_equal_fn(i1, num1, 2); relation_mutator_fn* filterCond1 = br.mk_filter_interpreted_fn(i1, cond3); relation_base* i3 = (*join1)(i2, i2); i3->display(std::cout); relation_transformer_fn* proj2 = br.mk_project_fn(*i3, 2, cols2); (*filterEq1)(i2); i2.display(std::cout << "no-op still full\n"); // no-op (*filterCond1)(i2); i2.display(std::cout << "x2 < x3\n"); // x2 < x3 (*filterId1)(i2); i2.display(std::cout << "id\n"); // x1 = x2 < x3 relation_fact fact1(ast_m); i2.display(std::cout << "Orig\n"); std::cout << "renamed "; for (unsigned i = 0; i < 3; ++i) { std::cout << cols3[i] << " "; } std::cout << "\n"; relation_base* i5 = (*ren1)(i2); i5->display(std::cout); //SASSERT(i2.empty()); relation_base* i4 = (*proj2)(*i3); i4->display(std::cout); // test that equivalence classes are expanded. // { x1 = x3, x0 < x1 x1 < x2} u { x2 = x3, x0 < x3 } = { x0 < x3 } { relation_base* b1 = br.mk_full(0, sig); relation_base* b2 = br.mk_full(0, sig); unsigned x1x3[2] = { 1, 3 }; unsigned x2x3[2] = { 2, 3 }; scoped_ptr<relation_mutator_fn> id1 = br.mk_filter_identical_fn(*b1, 2, x1x3); scoped_ptr<relation_mutator_fn> ltx0x1 = br.mk_filter_interpreted_fn(*b1, lt_x0x1); scoped_ptr<relation_mutator_fn> ltx1x2 = br.mk_filter_interpreted_fn(*b1, lt_x1x2); scoped_ptr<relation_mutator_fn> ltx0x3 = br.mk_filter_interpreted_fn(*b2, lt_x0x3); scoped_ptr<relation_mutator_fn> id2 = br.mk_filter_identical_fn(*b2, 2, x2x3); (*id1)(*b1); (*ltx0x1)(*b1); (*ltx1x2)(*b1); b2->display(std::cout << "b2:\n"); (*id2)(*b2); b2->display(std::cout << "b2:\n"); (*ltx0x3)(*b2); b2->display(std::cout << "b2:\n"); scoped_ptr<relation_union_fn> u = br.mk_union_fn(*b1, *b2, 0); b1->display(std::cout << "b1:\n"); b2->display(std::cout << "b2:\n"); (*u)(*b1, *b2, 0); b1->display(std::cout << "b1 u b2:\n"); // TBD check property; b1->deallocate(); b2->deallocate(); } // test that equivalence classes are expanded. // { x1 = x2 = x3, x0 < x1} u { x1 = x3, x0 < x3, x0 < x2 } = { x0 < x2, x0 < x3 } { relation_base* b1 = br.mk_full(0, sig); relation_base* b2 = br.mk_full(0, sig); unsigned x0x3[2] = { 0, 3 }; unsigned x1x3[2] = { 1, 3 }; unsigned x2x3[2] = { 2, 3 }; scoped_ptr<relation_mutator_fn> id1 = br.mk_filter_identical_fn(*b1, 2, x1x3); scoped_ptr<relation_mutator_fn> id2 = br.mk_filter_identical_fn(*b1, 2, x2x3); scoped_ptr<relation_mutator_fn> ltx0x1 = br.mk_filter_interpreted_fn(*b1, lt_x0x1); scoped_ptr<relation_mutator_fn> ltx0x2 = br.mk_filter_interpreted_fn(*b2, lt_x0x2); scoped_ptr<relation_mutator_fn> ltx0x3 = br.mk_filter_interpreted_fn(*b2, lt_x0x3); scoped_ptr<relation_mutator_fn> id3 = br.mk_filter_identical_fn(*b2, 2, x1x3); (*id1)(*b1); (*id2)(*b1); (*ltx0x1)(*b1); (*id3)(*b2); (*ltx0x2)(*b2); (*ltx0x3)(*b2); scoped_ptr<relation_union_fn> u = br.mk_union_fn(*b1, *b2, 0); b1->display(std::cout << "b1:\n"); b2->display(std::cout << "b2:\n"); (*u)(*b1, *b2, 0); b1->display(std::cout << "b1 u b2:\n"); // TBD check property; b1->deallocate(); b2->deallocate(); } i1.deallocate(); i2.deallocate(); i3->deallocate(); i4->deallocate(); i5->deallocate(); dealloc(join1); dealloc(proj1); dealloc(ren1); dealloc(union1); dealloc(filterId1); dealloc(filterEq1); dealloc(filterCond1); }
static void test_interval_relation() { smt_params params; ast_manager ast_m; register_engine re; context ctx(ast_m, re, params); arith_util autil(ast_m); relation_manager & m = ctx.get_rel_context()->get_rmanager(); m.register_plugin(alloc(interval_relation_plugin, m)); interval_relation_plugin& ip = dynamic_cast<interval_relation_plugin&>(*m.get_relation_plugin(symbol("interval_relation"))); SASSERT(&ip); relation_signature sig; sort* int_sort = autil.mk_int(); sig.push_back(int_sort); sig.push_back(int_sort); sig.push_back(int_sort); sig.push_back(int_sort); interval_relation& i1 = dynamic_cast<interval_relation&>(*ip.mk_empty(sig)); interval_relation& i2 = dynamic_cast<interval_relation&>(*ip.mk_full(0, sig)); i1.display(std::cout); i2.display(std::cout); SASSERT(i1.empty()); SASSERT(!i2.empty()); app_ref cond1(ast_m), cond2(ast_m), cond3(ast_m); app_ref cond4(ast_m), cond5(ast_m), cond6(ast_m); app_ref num1(ast_m); cond1 = autil.mk_le(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true)); cond2 = autil.mk_le(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(1), true)); cond3 = autil.mk_le(ast_m.mk_var(2, int_sort), autil.mk_numeral(rational(2), true)); cond4 = autil.mk_ge(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true)); cond5 = autil.mk_ge(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(0), true)); cond6 = autil.mk_ge(ast_m.mk_var(2, int_sort), autil.mk_numeral(rational(5), true)); num1 = autil.mk_numeral(rational(4), true); i2.filter_interpreted(cond1); i2.display(std::cout); // x0 <= 0 unsigned cols1[2] = { 1, 2}; unsigned cols2[2] = { 2, 3}; relation_join_fn* join1 = ip.mk_join_fn(i1, i2, 2, cols1, cols2); relation_transformer_fn* proj1 = ip.mk_project_fn(i1, 2, cols2); relation_transformer_fn* ren1 = ip.mk_rename_fn(i1, 2, cols2); relation_union_fn* union1 = ip.mk_union_fn(i1, i2, &i1); relation_mutator_fn* filterId1 = ip.mk_filter_identical_fn(i1, 2, cols1); relation_mutator_fn* filterEq1 = ip.mk_filter_equal_fn(i1, num1, 2); relation_mutator_fn* filterCond1 = ip.mk_filter_interpreted_fn(i1, cond2); relation_base* i3 = (*join1)(i2, i2); i3->display(std::cout); relation_transformer_fn* proj2 = ip.mk_project_fn(*i3, 2, cols2); (*filterEq1)(i2); i2.display(std::cout); // x0 <= 0 // x2 = 4 (*filterId1)(i2); i2.display(std::cout); // x0 <= 0 // x1 = x2 = 4 relation_fact fact1(ast_m); fact1.push_back(autil.mk_numeral(rational(0), true)); fact1.push_back(autil.mk_numeral(rational(4), true)); fact1.push_back(autil.mk_numeral(rational(4), true)); fact1.push_back(autil.mk_numeral(rational(5), true)); SASSERT(i2.contains_fact(fact1)); fact1[0] = autil.mk_numeral(rational(-1), true); SASSERT(i2.contains_fact(fact1)); fact1[0] = autil.mk_numeral(rational(1), true); SASSERT(!i2.contains_fact(fact1)); relation_base* i5 = (*ren1)(i2); i2.display(std::cout << "Orig\n"); i5->display(std::cout << "renamed 2 |-> 3 |-> 2\n"); (*filterCond1)(i2); i2.display(std::cout); // empty SASSERT(i2.empty()); relation_base* i4 = (*proj2)(*i3); i4->display(std::cout); i1.deallocate(); i2.deallocate(); i3->deallocate(); i4->deallocate(); i5->deallocate(); dealloc(join1); dealloc(proj1); dealloc(ren1); dealloc(union1); dealloc(filterId1); dealloc(filterEq1); dealloc(filterCond1); }
bool mk_interp_tail_simplifier::propagate_variable_equivalences(rule * r, rule_ref& res) { if (!m_context.get_params ().xform_tail_simplifier_pve ()) return false; unsigned u_len = r->get_uninterpreted_tail_size(); unsigned len = r->get_tail_size(); if (u_len == len) { return false; } m_todo.reset(); m_leqs.reset(); for (unsigned i = u_len; i < len; i++) { m_todo.push_back(r->get_tail(i)); SASSERT(!r->is_neg_tail(i)); } m_rule_subst.reset(r); expr_ref_vector trail(m); expr_ref tmp1(m), tmp2(m); bool found_something = false; #define TRY_UNIFY(_x,_y) if (m_rule_subst.unify(_x,_y)) { found_something = true; } #define IS_FLEX(_x) (is_var(_x) || m.is_value(_x)) while (!m_todo.empty()) { expr * arg1, *arg2; expr * t0 = m_todo.back(); m_todo.pop_back(); expr* t = t0; bool neg = m.is_not(t, t); if (is_var(t)) { TRY_UNIFY(t, neg ? m.mk_false() : m.mk_true()); } else if (!neg && m.is_and(t)) { app* a = to_app(t); m_todo.append(a->get_num_args(), a->get_args()); } else if (!neg && m.is_eq(t, arg1, arg2) && IS_FLEX(arg1) && IS_FLEX(arg2)) { TRY_UNIFY(arg1, arg2); } else if (m.is_iff(t, arg1, arg2)) { //determine the polarity of the equivalence and remove the negations while (m.is_not(arg1, arg1)) neg = !neg; while (m.is_not(arg2, arg2)) neg = !neg; if (!is_var(arg1)) { std::swap(arg1, arg2); } if (!IS_FLEX(arg1) || !IS_FLEX(arg2)) { // no-op } else if (is_var(arg1) && !neg) { TRY_UNIFY(arg1, arg2); } else if (is_var(arg1) && neg && m.is_true(arg2)) { TRY_UNIFY(arg1, m.mk_false()); } else if (is_var(arg1) && neg && m.is_false(arg2)) { TRY_UNIFY(arg1, m.mk_true()); } } else if (!neg && (a.is_le(t, arg1, arg2) || a.is_ge(t, arg2, arg1))) { tmp1 = a.mk_sub(arg1, arg2); tmp2 = a.mk_sub(arg2, arg1); if (false && m_leqs.contains(tmp2) && IS_FLEX(arg1) && IS_FLEX(arg2)) { TRY_UNIFY(arg1, arg2); } else { trail.push_back(tmp1); m_leqs.insert(tmp1); } } } if (!found_something) { return false; } TRACE("dl_interp_tail_simplifier_propagation_pre", tout << "will propagate rule:\n"; r->display(m_context, tout); );
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { if (m.is_not(f) && (m.is_and(args[0]) || m.is_or(args[0]))) { SASSERT(num == 1); expr_ref tmp(m); app* a = to_app(args[0]); m_app_args.reset(); for (expr* arg : *a) { m_brwr.mk_not(arg, tmp); m_app_args.push_back(tmp); } if (m.is_and(args[0])) { result = mk_or(m_app_args); } else { result = mk_and(m_app_args); } return BR_REWRITE2; } if (!m.is_and(f) && !m.is_or(f)) { return BR_FAILED; } if (num == 0) { if (m.is_and(f)) { result = m.mk_true(); } else { result = m.mk_false(); } return BR_DONE; } if (num == 1) { result = args[0]; return BR_DONE; } m_app_args.reset(); m_app_args.append(num, args); std::sort(m_app_args.c_ptr(), m_app_args.c_ptr()+m_app_args.size(), m_expr_cmp); remove_duplicates(m_app_args); bool have_rewritten_args = false; have_rewritten_args = detect_equivalences(m_app_args, m.is_or(f)); if (m_app_args.size()==1) { result = m_app_args[0].get(); } else { if (m.is_and(f)) { result = m.mk_and(m_app_args.size(), m_app_args.c_ptr()); } else { SASSERT(m.is_or(f)); result = m.mk_or(m_app_args.size(), m_app_args.c_ptr()); } } if (have_rewritten_args) { return BR_REWRITE1; } return BR_DONE; }
SWkeLoader::SWkeLoader() :m_hModWke(0) { SASSERT(!s_pInst); s_pInst=this; }
void reduce(proof* pf, proof_ref &out) { proof *res = nullptr; m_todo.reset(); m_todo.push_back(pf); ptr_buffer<proof> args; bool dirty = false; while (!m_todo.empty()) { proof *p, *tmp, *pp; unsigned todo_sz; p = m_todo.back(); if (m_cache.find(p, tmp)) { res = tmp; m_todo.pop_back(); continue; } dirty = false; args.reset(); todo_sz = m_todo.size(); for (unsigned i = 0, sz = m.get_num_parents(p); i < sz; ++i) { pp = m.get_parent(p, i); if (m_cache.find(pp, tmp)) { args.push_back(tmp); dirty = dirty || pp != tmp; } else { m_todo.push_back(pp); } } if (todo_sz < m_todo.size()) { continue; } else { m_todo.pop_back(); } if (m.is_hypothesis(p)) { // hyp: replace by a corresponding unit if (m_units.find(m.get_fact(p), tmp)) { res = tmp; } else { res = p; } } else if (!dirty) { res = p; } else if (m.is_lemma(p)) { //lemma: reduce the premise; remove reduced consequences from conclusion SASSERT(args.size() == 1); res = mk_lemma_core(args.get(0), m.get_fact(p)); compute_mark1(res); } else if (m.is_unit_resolution(p)) { // unit: reduce units; reduce the first premise; rebuild unit resolution res = mk_unit_resolution_core(args.size(), args.c_ptr()); compute_mark1(res); } else { // other: reduce all premises; reapply if (m.has_fact(p)) { args.push_back(to_app(m.get_fact(p))); } SASSERT(p->get_decl()->get_arity() == args.size()); res = m.mk_app(p->get_decl(), args.size(), (expr * const*)args.c_ptr()); m_pinned.push_back(res); compute_mark1(res); } SASSERT(res); m_cache.insert(p, res); if (m.has_fact(res) && m.is_false(m.get_fact(res))) { break; } } out = res; }
parameter float_decl_plugin::translate(parameter const & p, decl_plugin & target) { SASSERT(p.is_external()); float_decl_plugin & _target = static_cast<float_decl_plugin&>(target); return parameter(_target.mk_id(m_values[p.get_ext_id()]), true); }
~SRicheditDropTarget() { SASSERT(pserv); pserv->Release(); }
void float_decl_plugin::recycled_id(unsigned id) { SASSERT(m_value_table.contains(id)); m_value_table.erase(id); m_id_gen.recycle(id); m_fm.del(m_values[id]); }
void extension_model_converter::operator()(model_ref & md, unsigned goal_idx) { SASSERT(goal_idx == 0); TRACE("extension_mc", model_v2_pp(tout, *md); display_decls_info(tout, md););
func_decl * float_decl_plugin::mk_value_decl(mpf const & v) { parameter p(mk_id(v), true); SASSERT(p.is_external()); sort * s = mk_float_sort(v.get_ebits(), v.get_sbits()); return m_manager->mk_const_decl(symbol("float"), s, func_decl_info(m_family_id, OP_FLOAT_VALUE, 1, &p)); }
void SSplitWnd::OnMouseMove( UINT nFlags,CPoint pt ) { if(-1==m_iDragSep) return; //将列表分裂成两组。 SplitPaneList lstPane1,lstPane2; SplitPaneList lstPriority1,lstPriority2; for(int i=0;i<(int)m_lstPane.GetCount();i++) { if(i <= m_iDragSep) lstPane1.Add(m_lstPane[i]); else lstPane2.Add(m_lstPane[i]); } for(int i=0;i<(int)m_lstPriority.GetCount();i++) { SSplitPane *pane = m_lstPriority[i]; int idx = ArrayFind(m_lstPane,pane); SASSERT(idx!=-1); if(idx<=m_iDragSep) lstPriority1.Add(pane); else lstPriority2.Add(pane); } CPoint diffPoint = m_ptDragPrev; m_ptDragPrev = pt; diffPoint = m_ptDragPrev - diffPoint; int diff = m_orintation == Vertical ? diffPoint.x : diffPoint.y; PANESIZELIST lstPaneSize1,lstPaneSize2; FatchPaneSizeInfo(lstPriority1,lstPaneSize1); FatchPaneSizeInfo(lstPriority2,lstPaneSize2); if(diff > 0) { int maxShrink = 0, maxExtent =0; for(int i=0; i< (int)lstPaneSize1.GetCount();i++) { maxExtent += lstPaneSize1[i].maximum - lstPaneSize1[i].actural; } for(int i=0;i< (int)lstPaneSize2.GetCount();i++) { maxShrink += lstPaneSize2[i].actural - lstPaneSize2[i].minimum; } diff = min(diff, min(maxShrink,maxExtent)); if(diff==0) return; //伸长part1 int idxPrev = ArrayFind(lstPriority1,lstPane1.GetAt(lstPane1.GetCount()-1)); SASSERT(idxPrev != -1); PANESIZE & paneSize1 = lstPaneSize1[idxPrev]; int max_digest =paneSize1.maximum - paneSize1.actural; if(max_digest>diff) { paneSize1.actural += diff; }else { paneSize1.actural += max_digest; PANESIZE szBackup = paneSize1; lstPaneSize1.RemoveAt(idxPrev); int remain = diff - max_digest; AdjustPanesSize(lstPaneSize1,remain); lstPaneSize1.InsertAt(idxPrev,szBackup); } //压缩part2 int idxNext = ArrayFind(lstPriority2,lstPane2[0]); SASSERT(idxNext != -1); PANESIZE & paneSize2 = lstPaneSize2[idxNext]; max_digest =paneSize2.actural - paneSize2.minimum; if(max_digest > diff) { paneSize2.actural -= diff; }else { paneSize2.actural -= max_digest; PANESIZE szBackup=paneSize2; lstPaneSize2.RemoveAt(idxNext); int remain = max_digest - diff;//remain < 0 AdjustPanesSize(lstPaneSize2,remain); lstPaneSize2.InsertAt(idxNext,szBackup); } }else { int maxShrink = 0, maxExtent =0; for(int i=0; i< (int)lstPaneSize2.GetCount();i++) { maxExtent += lstPaneSize2[i].maximum - lstPaneSize2[i].actural; } for(int i=0;i< (int)lstPaneSize1.GetCount();i++) { maxShrink += lstPaneSize1[i].actural - lstPaneSize1[i].minimum; } diff *= -1; diff = min(diff, min(maxShrink,maxExtent)); if(diff == 0) return; //压缩part1 int idxPrev = ArrayFind(lstPriority1,lstPane1.GetAt(lstPane1.GetCount()-1)); SASSERT(idxPrev != -1); PANESIZE & paneSize1 = lstPaneSize1[idxPrev]; int max_digest =paneSize1.actural - paneSize1.minimum; if(max_digest>diff) { paneSize1.actural -= diff; }else { paneSize1.actural -= max_digest; PANESIZE szBackup = paneSize1; lstPaneSize1.RemoveAt(idxPrev); int remain = max_digest - diff; //remain < 0 AdjustPanesSize(lstPaneSize1,remain); lstPaneSize1.InsertAt(idxPrev,szBackup); } //伸长part2 int idxNext = ArrayFind(lstPriority2,lstPane2[0]); SASSERT(idxNext != -1); PANESIZE & paneSize2 = lstPaneSize2[idxNext]; max_digest = paneSize2.maximum - paneSize2.actural; if(max_digest > diff) { paneSize2.actural += diff; }else { paneSize2.actural += max_digest; PANESIZE szBackup=paneSize2; lstPaneSize2.RemoveAt(idxNext); int remain = diff- max_digest; AdjustPanesSize(lstPaneSize2,remain); lstPaneSize2.InsertAt(idxNext,szBackup); } diff *= -1; } //根据新分配的窗口大小重置窗口位置 CRect rcClient = GetClientRect(); int nOffset = m_orintation == Vertical? rcClient.left: rcClient.top; nOffset = ResetPanesPostion(lstPane1,lstPriority1,lstPaneSize1,nOffset); ResetPanesPostion(lstPane2,lstPriority2,lstPaneSize2,nOffset); Invalidate(); }
unsigned float_util::get_sbits(sort * s) { SASSERT(is_float(s)); return static_cast<unsigned>(s->get_parameter(1).get_int()); }
/** \brief Return the size of the inductive datatype. Pre-condition: The given argument constains the parameters of an inductive datatype. */ static sort_size get_datatype_size(parameter const * parameters) { unsigned num_types = parameters[0].get_int(); unsigned tid = parameters[1].get_int(); buffer<sort_size> szs(num_types, sort_size()); buffer<status> already_found(num_types, WHITE); buffer<unsigned> todo; todo.push_back(tid); while (!todo.empty()) { unsigned tid = todo.back(); if (already_found[tid] == BLACK) { todo.pop_back(); continue; } already_found[tid] = GRAY; unsigned o = parameters[2 + 2*tid + 1].get_int(); // constructor offset unsigned num_constructors = parameters[o].get_int(); bool is_very_big = false; bool can_process = true; for (unsigned s = 1; s <= num_constructors; s++) { unsigned k_i = parameters[o+s].get_int(); unsigned num_accessors = parameters[k_i+2].get_int(); for (unsigned r = 0; r < num_accessors; r++) { parameter const & a_type = parameters[k_i+4 + 2*r]; if (a_type.is_int()) { int tid_prime = a_type.get_int(); switch (already_found[tid_prime]) { case WHITE: todo.push_back(tid_prime); can_process = false; break; case GRAY: // type is recursive return sort_size(); case BLACK: break; } } else { SASSERT(a_type.is_ast()); sort * ty = to_sort(a_type.get_ast()); if (ty->is_infinite()) { // type is infinite return sort_size(); } else if (ty->is_very_big()) { is_very_big = true; } } } } if (can_process) { todo.pop_back(); already_found[tid] = BLACK; if (is_very_big) { szs[tid] = sort_size::mk_very_big(); } else { // the type is not infinite nor the number of elements is infinite... // computing the number of elements rational num; for (unsigned s = 1; s <= num_constructors; s++) { unsigned k_i = parameters[o+s].get_int(); unsigned num_accessors = parameters[k_i+2].get_int(); rational c_num(1); for (unsigned r = 0; r < num_accessors; r++) { parameter const & a_type = parameters[k_i+4 + 2*r]; if (a_type.is_int()) { int tid_prime = a_type.get_int(); SASSERT(!szs[tid_prime].is_infinite() && !szs[tid_prime].is_very_big()); c_num *= rational(szs[tid_prime].size(),rational::ui64()); } else { SASSERT(a_type.is_ast()); sort * ty = to_sort(a_type.get_ast()); SASSERT(!ty->is_infinite() && !ty->is_very_big()); c_num *= rational(ty->get_num_elements().size(), rational::ui64()); } } num += c_num; } szs[tid] = sort_size(num); } } } return szs[tid]; }
bool checker::check_core(expr * n, bool is_true) { SASSERT(m_manager.is_bool(n)); if (m_context.b_internalized(n) && m_context.is_relevant(n)) { lbool val = m_context.get_assignment(n); return val != l_undef && is_true == (val == l_true); } if (!is_app(n)) return false; app * a = to_app(n); if (a->get_family_id() == m_manager.get_basic_family_id()) { switch (a->get_decl_kind()) { case OP_TRUE: return is_true; case OP_FALSE: return !is_true; case OP_NOT: return check(a->get_arg(0), !is_true); case OP_OR: return is_true ? any_arg(a, true) : all_args(a, false); case OP_AND: return is_true ? all_args(a, true) : any_arg(a, false); case OP_IFF: if (is_true) { return (check(a->get_arg(0), true) && check(a->get_arg(1), true)) || (check(a->get_arg(0), false) && check(a->get_arg(1), false)); } else { return (check(a->get_arg(0), true) && check(a->get_arg(1), false)) || (check(a->get_arg(0), false) && check(a->get_arg(1), true)); } case OP_ITE: { if (m_context.lit_internalized(a->get_arg(0)) && m_context.is_relevant(a->get_arg(0))) { switch (m_context.get_assignment(a->get_arg(0))) { case l_false: return check(a->get_arg(2), is_true); case l_undef: return false; case l_true: return check(a->get_arg(1), is_true); } } return check(a->get_arg(1), is_true) && check(a->get_arg(2), is_true); } case OP_EQ: { enode * lhs = get_enode_eq_to(a->get_arg(0)); enode * rhs = get_enode_eq_to(a->get_arg(1)); if (lhs && rhs && m_context.is_relevant(lhs) && m_context.is_relevant(rhs)) { if (is_true && lhs->get_root() == rhs->get_root()) return true; // if (!is_true && m_context.is_ext_diseq(lhs, rhs, 2)) if (!is_true && m_context.is_diseq(lhs, rhs)) return true; } return false; } default: break; } } enode * e = get_enode_eq_to(a); if (e && e->is_bool() && m_context.is_relevant(e)) { lbool val = m_context.get_assignment(e->get_owner()); return val != l_undef && is_true == (val == l_true); } return false; }
func_decl * datatype_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (num_parameters < 2 || !parameters[0].is_ast() || !is_sort(parameters[0].get_ast())) { m_manager->raise_exception("invalid parameters for datatype operator"); return 0; } sort * datatype = to_sort(parameters[0].get_ast()); if (datatype->get_family_id() != m_family_id || datatype->get_decl_kind() != DATATYPE_SORT) { m_manager->raise_exception("invalid parameters for datatype operator"); return 0; } for (unsigned i = 1; i < num_parameters; i++) { if (!parameters[i].is_int()) { m_manager->raise_exception("invalid parameters for datatype operator"); return 0; } } unsigned c_idx = parameters[1].get_int(); unsigned tid = datatype->get_parameter(1).get_int(); unsigned o = datatype->get_parameter(2 + 2 * tid + 1).get_int(); unsigned num_constructors = datatype->get_parameter(o).get_int(); if (c_idx >= num_constructors) { m_manager->raise_exception("invalid parameters for datatype operator"); return 0; } unsigned k_i = datatype->get_parameter(o + 1 + c_idx).get_int(); switch (k) { case OP_DT_CONSTRUCTOR: if (num_parameters != 2) { m_manager->raise_exception("invalid parameters for datatype constructor"); return 0; } else { symbol c_name = datatype->get_parameter(k_i).get_symbol(); unsigned num_accessors = datatype->get_parameter(k_i + 2).get_int(); if (num_accessors != arity) { m_manager->raise_exception("invalid domain size for datatype constructor"); return 0; } // // the reference count to domain could be 0. // we need to ensure that creating a temporary // copy of the same type causes a free. // sort_ref_vector domain_check(*m_manager); for (unsigned r = 0; r < num_accessors; r++) { sort_ref ty(*m_manager); ty = get_type(*m_manager, m_family_id, datatype, datatype->get_parameter(k_i + 4 + 2*r)); domain_check.push_back(ty); if (ty != domain[r]) { m_manager->raise_exception("invalid domain for datatype constructor"); return 0; } } func_decl_info info(m_family_id, k, num_parameters, parameters); info.m_private_parameters = true; SASSERT(info.private_parameters()); return m_manager->mk_func_decl(c_name, arity, domain, datatype, info); } case OP_DT_RECOGNISER: if (num_parameters != 2 || arity != 1 || domain[0] != datatype) { m_manager->raise_exception("invalid parameters for datatype recogniser"); return 0; } else { symbol r_name = datatype->get_parameter(k_i + 1).get_symbol(); sort * b = m_manager->mk_bool_sort(); func_decl_info info(m_family_id, k, num_parameters, parameters); info.m_private_parameters = true; SASSERT(info.private_parameters()); return m_manager->mk_func_decl(r_name, arity, domain, b, info); } case OP_DT_ACCESSOR: if (num_parameters != 3 || arity != 1 || domain[0] != datatype) { m_manager->raise_exception("invalid parameters for datatype accessor"); return 0; } else { unsigned a_idx = parameters[2].get_int(); unsigned num_accessors = datatype->get_parameter(k_i + 2).get_int(); if (a_idx >= num_accessors) { m_manager->raise_exception("invalid datatype accessor"); return 0; } symbol a_name = datatype->get_parameter(k_i + 3 + 2*a_idx).get_symbol(); sort * a_type = get_type(*m_manager, m_family_id, datatype, datatype->get_parameter(k_i + 4 + 2*a_idx)); func_decl_info info(m_family_id, k, num_parameters, parameters); info.m_private_parameters = true; SASSERT(info.private_parameters()); return m_manager->mk_func_decl(a_name, arity, domain, a_type, info); } break; default: m_manager->raise_exception("invalid datatype operator kind"); return 0; } }
sort * bvarray2uf_rewriter_cfg::get_value_sort(sort * s) { SASSERT(s->get_num_parameters() >= 2); parameter const & p = s->get_parameter(s->get_num_parameters() - 1); SASSERT(p.is_ast() && is_sort(to_sort(p.get_ast()))); return to_sort(p.get_ast()); }
void user_sort_factory::register_value(expr * n) { SASSERT(!is_finite(m_manager.get_sort(n))); simple_factory<unsigned>::register_value(n); }
void gparams::reset() { SASSERT(g_imp != 0); g_imp->reset(); }
void prop_solver::assert_expr(expr * form) { SASSERT(!m_in_level); m_contexts[0]->assert_expr(form); m_contexts[1]->assert_expr(form); IF_VERBOSE(21, verbose_stream() << "$ asserted " << mk_pp(form, m) << "\n";);
br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { br_status st = BR_FAILED; SASSERT(f->get_family_id() == get_fid()); switch (f->get_decl_kind()) { case OP_TO_FLOAT: st = mk_to_fp(f, num_args, args, result); break; case OP_FLOAT_ADD: SASSERT(num_args == 3); st = mk_add(args[0], args[1], args[2], result); break; case OP_FLOAT_SUB: SASSERT(num_args == 3); st = mk_sub(args[0], args[1], args[2], result); break; case OP_FLOAT_NEG: SASSERT(num_args == 1); st = mk_neg(args[0], result); break; case OP_FLOAT_MUL: SASSERT(num_args == 3); st = mk_mul(args[0], args[1], args[2], result); break; case OP_FLOAT_DIV: SASSERT(num_args == 3); st = mk_div(args[0], args[1], args[2], result); break; case OP_FLOAT_REM: SASSERT(num_args == 2); st = mk_rem(args[0], args[1], result); break; case OP_FLOAT_ABS: SASSERT(num_args == 1); st = mk_abs(args[0], result); break; case OP_FLOAT_MIN: SASSERT(num_args == 2); st = mk_min(args[0], args[1], result); break; case OP_FLOAT_MAX: SASSERT(num_args == 2); st = mk_max(args[0], args[1], result); break; case OP_FLOAT_FMA: SASSERT(num_args == 4); st = mk_fma(args[0], args[1], args[2], args[3], result); break; case OP_FLOAT_SQRT: SASSERT(num_args == 2); st = mk_sqrt(args[0], args[1], result); break; case OP_FLOAT_ROUND_TO_INTEGRAL: SASSERT(num_args == 2); st = mk_round(args[0], args[1], result); break; case OP_FLOAT_EQ: SASSERT(num_args == 2); st = mk_float_eq(args[0], args[1], result); break; case OP_FLOAT_LT: SASSERT(num_args == 2); st = mk_lt(args[0], args[1], result); break; case OP_FLOAT_GT: SASSERT(num_args == 2); st = mk_gt(args[0], args[1], result); break; case OP_FLOAT_LE: SASSERT(num_args == 2); st = mk_le(args[0], args[1], result); break; case OP_FLOAT_GE: SASSERT(num_args == 2); st = mk_ge(args[0], args[1], result); break; case OP_FLOAT_IS_ZERO: SASSERT(num_args == 1); st = mk_is_zero(args[0], result); break; case OP_FLOAT_IS_NZERO: SASSERT(num_args == 1); st = mk_is_nzero(args[0], result); break; case OP_FLOAT_IS_PZERO: SASSERT(num_args == 1); st = mk_is_pzero(args[0], result); break; case OP_FLOAT_IS_NAN: SASSERT(num_args == 1); st = mk_is_nan(args[0], result); break; case OP_FLOAT_IS_INF: SASSERT(num_args == 1); st = mk_is_inf(args[0], result); break; case OP_FLOAT_IS_NORMAL: SASSERT(num_args == 1); st = mk_is_normal(args[0], result); break; case OP_FLOAT_IS_SUBNORMAL: SASSERT(num_args == 1); st = mk_is_subnormal(args[0], result); break; case OP_FLOAT_IS_NEGATIVE: SASSERT(num_args == 1); st = mk_is_negative(args[0], result); break; case OP_FLOAT_IS_POSITIVE: SASSERT(num_args == 1); st = mk_is_positive(args[0], result); break; case OP_FLOAT_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break; case OP_FLOAT_FP: SASSERT(num_args == 3); st = mk_fp(args[0], args[1], args[2], result); break; case OP_FLOAT_TO_UBV: SASSERT(num_args == 2); st = mk_to_ubv(args[0], args[1], result); break; case OP_FLOAT_TO_SBV: SASSERT(num_args == 2); st = mk_to_sbv(args[0], args[1], result); break; case OP_FLOAT_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; } return st; }