mirror of
https://github.com/Z3Prover/z3
synced 2025-04-07 18:05:21 +00:00
93 lines
2.9 KiB
C++
93 lines
2.9 KiB
C++
/*++
|
|
Copyright (c) 2006 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
reduce_args.h
|
|
|
|
Abstract:
|
|
|
|
<abstract>
|
|
|
|
Author:
|
|
|
|
Leonardo de Moura (leonardo) 2010-04-05.
|
|
|
|
Revision History:
|
|
|
|
Make it a strategy 2011-07-26.
|
|
|
|
--*/
|
|
#ifndef _REDUCE_ARGS_H_
|
|
#define _REDUCE_ARGS_H_
|
|
|
|
#include"assertion_set_strategy.h"
|
|
|
|
MK_ST_EXCEPTION(reduce_args_exception);
|
|
|
|
/**
|
|
\brief Reduce the number of arguments in function applications.
|
|
|
|
Example, suppose we have a function f with 2 arguments.
|
|
There are 1000 applications of this function, but the first argument is always "a", "b" or "c".
|
|
Thus, we replace the f(t1, t2)
|
|
with
|
|
f_a(t2) if t1 = a
|
|
f_b(t2) if t2 = b
|
|
f_c(t2) if t2 = c
|
|
|
|
Since f_a, f_b, f_c are new symbols, satisfiability is preserved.
|
|
|
|
This transformation is very similar in spirit to the Ackermman's reduction.
|
|
|
|
This transformation should work in the following way:
|
|
|
|
1- Create a mapping decl2arg_map from declarations to tuples of booleans, an entry [f -> (true, false, true)]
|
|
means that f is a declaration with 3 arguments where the first and third arguments are always values.
|
|
2- Traverse the formula and populate the mapping.
|
|
For each function application f(t1, ..., tn) do
|
|
a) Create a boolean tuple (is_value(t1), ..., is_value(tn)) and do
|
|
the logical-and with the tuple that is already in the mapping. If there is no such tuple
|
|
in the mapping, we just add a new entry.
|
|
|
|
If all entries are false-tuples, then there is nothing to be done. The transformation is not applicable.
|
|
|
|
Now, we create a mapping decl2new_decl from (decl, val_1, ..., val_n) to decls. Note that, n may be different for each entry,
|
|
but it is the same for the same declaration.
|
|
For example, suppose we have [f -> (true, false, true)] in decl2arg_map, and applications f(1, a, 2), f(1, b, 2), f(1, b, 3), f(2, b, 3), f(2, c, 3) in the formula.
|
|
Then, decl2arg_map would contain
|
|
(f, 1, 2) -> f_1_2
|
|
(f, 1, 3) -> f_1_3
|
|
(f, 2, 3) -> f_2_3
|
|
where f_1_2, f_1_3 and f_2_3 are new function symbols.
|
|
Using the new map, we can replace the occurrences of f.
|
|
*/
|
|
class reduce_args : public assertion_set_strategy {
|
|
struct imp;
|
|
imp * m_imp;
|
|
params_ref m_params;
|
|
public:
|
|
reduce_args(ast_manager & m, params_ref const & p = params_ref());
|
|
virtual ~reduce_args();
|
|
|
|
ast_manager & m () const;
|
|
|
|
virtual void updt_params(params_ref const & p);
|
|
static void get_param_descrs(param_descrs & r);
|
|
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
|
|
|
|
virtual void operator()(assertion_set & s, model_converter_ref & mc);
|
|
|
|
virtual void cleanup();
|
|
|
|
virtual void collect_statistics(statistics & st) const;
|
|
virtual void reset_statistics();
|
|
protected:
|
|
virtual void set_cancel(bool f);
|
|
};
|
|
|
|
as_st * mk_reduce_args(ast_manager & m, params_ref const & p = params_ref());
|
|
|
|
#endif /* _REDUCE_ARGS_H_ */
|
|
|