#include "ast/reg_decl_plugins.h"
#include "cmd_context/cmd_context.h"
#include "parsers/smt2/smt2parser.h"
#include "smt/smt_context.h"
#include <sstream>
static lbool check_ho_qsolver(char const* input, bool ho_qmatcher) {
ast_manager m;
reg_decl_plugins(m);
cmd_context cmd(false, &m);
std::istringstream is(input);
VERIFY(parse_smt2_commands(cmd, is));
smt_params params;
params.m_ematching = false;
params.m_mbqi = false;
params.m_ho_matching = true;
params.m_ho_qmatcher = ho_qmatcher;
params.m_term_enumeration = true;
params.m_ho_matching_bound = 100;
smt::context ctx(m, params);
for (expr* assertion : cmd.assertions())
ctx.assert_expr(assertion);
return ctx.check();
}
void tst_ho_qsolver() {
char const* cantor =
"(declare-sort U 0)\n"
"(declare-const a (Array U U))\n"
"(declare-const b (Array U U))\n"
"(declare-fun q ((Array U U)) Bool)\n"
"(assert (forall ((P (Array U Bool)) (X U))\n"
" (=> (select P (select a X)) (select P (select b X)))))\n"
"(assert (q b))\n"
"(assert (not (q a)))\n";
VERIFY(l_undef == check_ho_qsolver(cantor, false));
VERIFY(l_false == check_ho_qsolver(cantor, true));
char const* reversed =
"(declare-sort U 0)\n"
"(declare-const a (Array U U))\n"
"(declare-const b (Array U U))\n"
"(declare-fun q ((Array U U)) Bool)\n"
"(assert (forall ((P (Array U Bool)) (X U))\n"
" (=> (select P (select b X)) (select P (select a X)))))\n"
"(assert (q b))\n"
"(assert (not (q a)))\n";
VERIFY(l_false == check_ho_qsolver(reversed, true));
char const* many_sorted =
"(declare-sort U 0)\n"
"(declare-sort V 0)\n"
"(declare-const a (Array U V))\n"
"(declare-const b (Array U V))\n"
"(declare-fun g ((Array U V)) Bool)\n"
"(assert (forall ((P (Array V Bool)) (X U))\n"
" (=> (select P (select a X)) (select P (select b X)))))\n"
"(assert (g b))\n"
"(assert (not (g a)))\n";
VERIFY(l_false == check_ho_qsolver(many_sorted, true));
char const* fixed_point =
"(declare-sort U 0)\n"
"(declare-const P\n"
" (Array (Array (Array U U) U)\n"
" (Array (Array (Array U U) U) Bool)))\n"
"(assert (forall ((Z (Array (Array U U) U)))\n"
" (select (select P Z) Z)))\n"
"(assert (forall ((X (Array (Array U U) U)))\n"
" (not (select\n"
" (select P\n"
" (lambda ((u (Array U U)))\n"
" (select u (select X (lambda ((v U)) v)))))\n"
" X))))\n";
VERIFY(l_undef == check_ho_qsolver(fixed_point, false));
VERIFY(l_undef == check_ho_qsolver(fixed_point, true));
}