1 /*++
2 Copyright (c) 2011 Microsoft Corporation
3 
4 Module Name:
5 
6     mk_simplified_app.cpp
7 
8 Abstract:
9 
10     Functor for creating new simplified applications
11 
12 Author:
13 
14     Leonardo (leonardo) 2011-06-06
15 
16 Notes:
17 
18 --*/
19 #include "ast/rewriter/mk_simplified_app.h"
20 #include "ast/rewriter/bool_rewriter.h"
21 #include "ast/rewriter/arith_rewriter.h"
22 #include "ast/rewriter/bv_rewriter.h"
23 #include "ast/rewriter/datatype_rewriter.h"
24 #include "ast/rewriter/array_rewriter.h"
25 #include "ast/rewriter/fpa_rewriter.h"
26 
27 struct mk_simplified_app::imp {
28     ast_manager &         m;
29     bool_rewriter         m_b_rw;
30     arith_rewriter        m_a_rw;
31     bv_rewriter           m_bv_rw;
32     array_rewriter        m_ar_rw;
33     datatype_rewriter     m_dt_rw;
34     fpa_rewriter          m_f_rw;
35 
impmk_simplified_app::imp36     imp(ast_manager & _m, params_ref const & p):
37         m(_m),
38         m_b_rw(m, p),
39         m_a_rw(m, p),
40         m_bv_rw(m, p),
41         m_ar_rw(m, p),
42         m_dt_rw(m),
43         m_f_rw(m, p) {
44     }
45 
mk_coremk_simplified_app::imp46     br_status mk_core(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
47         family_id fid = f->get_family_id();
48         if (fid == null_family_id)
49             return BR_FAILED;
50         br_status st = BR_FAILED;
51         if (fid == m_b_rw.get_fid()) {
52             decl_kind k = f->get_decl_kind();
53             if (k == OP_EQ) {
54                 // theory dispatch for =
55                 SASSERT(num == 2);
56                 family_id s_fid = args[0]->get_sort()->get_family_id();
57                 if (s_fid == m_a_rw.get_fid())
58                     st = m_a_rw.mk_eq_core(args[0], args[1], result);
59                 else if (s_fid == m_bv_rw.get_fid())
60                     st = m_bv_rw.mk_eq_core(args[0], args[1], result);
61                 else if (s_fid == m_dt_rw.get_fid())
62                     st = m_dt_rw.mk_eq_core(args[0], args[1], result);
63                 else if (s_fid == m_f_rw.get_fid())
64                     st = m_f_rw.mk_eq_core(args[0], args[1], result);
65                 else if (s_fid == m_ar_rw.get_fid())
66                     st = m_ar_rw.mk_eq_core(args[0], args[1], result);
67 
68                 if (st != BR_FAILED)
69                     return st;
70             }
71             return m_b_rw.mk_app_core(f, num, args, result);
72         }
73         if (fid == m_a_rw.get_fid())
74             return m_a_rw.mk_app_core(f, num, args, result);
75         if (fid == m_bv_rw.get_fid())
76             return m_bv_rw.mk_app_core(f, num, args, result);
77         if (fid == m_ar_rw.get_fid())
78             return m_ar_rw.mk_app_core(f, num, args, result);
79         if (fid == m_dt_rw.get_fid())
80             return m_dt_rw.mk_app_core(f, num, args, result);
81         if (fid == m_f_rw.get_fid())
82             return m_f_rw.mk_app_core(f, num, args, result);
83         return BR_FAILED;
84     }
85 };
86 
87 
mk_simplified_app(ast_manager & m,params_ref const & p)88 mk_simplified_app::mk_simplified_app(ast_manager & m, params_ref const & p):
89     m_imp(alloc(imp, m, p)) {
90 }
91 
~mk_simplified_app()92 mk_simplified_app::~mk_simplified_app() {
93     dealloc(m_imp);
94 }
95 
mk_core(func_decl * decl,unsigned num,expr * const * args,expr_ref & result)96 br_status mk_simplified_app::mk_core(func_decl * decl, unsigned num, expr * const * args, expr_ref & result) {
97     return m_imp->mk_core(decl, num, args, result);
98 }
99 
operator ()(func_decl * decl,unsigned num,expr * const * args,expr_ref & result)100 void mk_simplified_app::operator()(func_decl * decl, unsigned num, expr * const * args, expr_ref & result) {
101     result = nullptr;
102     mk_core(decl, num, args, result);
103     if (!result)
104         result = m_imp->m.mk_app(decl, num, args);
105     // TODO: if the result of mk_core is different from BR_FAILED, then the
106     // result is not really simplified.
107 }
108