MathSAT C API Example(More examples can be found in the MathSAT distribution.)
/*
* api_example.c: A simple example of usage of the MathSAT API
* author: Alberto Griggio <griggio@fbk.eu>
*
* to compile: gcc api_example.c -I${MSAT_DIR}/include -L${MSAT_DIR}/lib
* -lmathsat -lgmpxx -lgmp -lstdc++ -o api_example
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "mathsat.h"
static void example1();
static void example_interpolation1();
static void example_interpolation2();
static void example_unsat_core();
int main()
{
printf("MathSAT API Examples\n");
printf("Press RETURN to begin...\n");
getchar();
example1();
printf("Press RETURN to continue...\n");
getchar();
example_interpolation1();
printf("Press RETURN to continue...\n");
getchar();
example_interpolation2();
printf("Press RETURN to continue...\n");
getchar();
example_unsat_core();
return 0;
}
static msat_term create_a_formula(msat_env env)
{
const char *vn[] = {"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8"};
msat_decl vars[sizeof(vn)/sizeof(vn[0])];
const char *fn[] = {"f", "h"};
msat_decl funcs[sizeof(fn)/sizeof(fn[0])];
unsigned int i;
msat_term res, tmp;
msat_type rat_tp, func_tp;
msat_type paramtps[1];
/* get the rat type (aka sort) */
rat_tp = msat_get_rational_type(env);
assert(!MSAT_ERROR_TYPE(rat_tp));
/* first, let's declare the functions we are going to use */
for (i = 0; i < sizeof(vn)/sizeof(vn[0]); ++i) {
vars[i] = msat_declare_function(env, vn[i], rat_tp);
assert(!MSAT_ERROR_DECL(vars[i]));
}
/* create the type for the functions */
paramtps[0] = rat_tp;
func_tp = msat_get_function_type(env, paramtps, 1, rat_tp);
assert(!MSAT_ERROR_TYPE(func_tp));
for (i = 0; i < sizeof(fn)/sizeof(fn[0]); ++i) {
funcs[i] = msat_declare_function(env, fn[i], func_tp);
assert(!MSAT_ERROR_DECL(funcs[i]));
}
/* we can create terms in two ways. The easiest one is by using
* msat_from_string. The syntax is that of SMT-LIBv2 */
res = msat_from_string(
env, "(and (= v3 (h v0)) (= v4 (h v1)) (= v6 (f v2)) (= v7 (f v5)))");
assert(!MSAT_ERROR_TERM(res));
/* the other one is by using the various msat_make_* functions */
tmp = msat_make_leq(env,
msat_make_constant(env, vars[1]),
msat_make_constant(env, vars[0]));
res = msat_make_and(env, res, tmp);
tmp = msat_make_not(env,
msat_make_equal(env,
msat_make_constant(env, vars[6]),
msat_make_constant(env, vars[7])));
res = msat_make_and(env, res, tmp);
tmp = msat_from_string(env, "(and (<= v0 v1) (= v2 (- v3 v4)))");
res = msat_make_and(env, res, tmp);
return res;
}
static void print_model(msat_env env)
{
/* we use a model iterator to retrieve the model values for all the
* variables, and the necessary function instantiations */
msat_model_iterator iter = msat_create_model_iterator(env);
assert(!MSAT_ERROR_MODEL_ITERATOR(iter));
printf("Model:\n");
while (msat_model_iterator_has_next(iter)) {
msat_term t, v;
char *s;
msat_model_iterator_next(iter, &t;, &v;);
s = msat_term_repr(t);
assert(s);
printf(" %s = ", s);
msat_free(s);
s = msat_term_repr(v);
assert(s);
printf("%s\n", s);
msat_free(s);
}
msat_destroy_model_iterator(iter);
}
/*
* This example shows the basic usage of the API for creating formulas,
* checking satisfiability, and using the solver incrementally
*/
static void example1()
{
msat_config cfg;
msat_env env;
msat_term formula;
msat_result status;
int res;
char *s;
printf("\nExample 1\n");
/* first, we create a configuration */
cfg = msat_create_config();
/* enable model generation */
msat_set_option(cfg, "model_generation", "true");
/* create an environment with the above configuration */
env = msat_create_env(cfg);
/* create a formula and assert it permanently */
formula = create_a_formula(env);
res = msat_assert_formula(env, formula);
assert(res == 0);
s = msat_term_repr(formula);
assert(s);
printf("Asserted: %s\n", s);
msat_free(s);
/* incrementally add an assertion */
res = msat_push_backtrack_point(env);
assert(res == 0);
formula = msat_from_string(env, "(= v5 0)");
assert(!MSAT_ERROR_TERM(formula));
res = msat_assert_formula(env, formula);
assert(res == 0);
s = msat_term_repr(formula);
assert(s);
printf("Added constraint: %s\n", s);
/* check satisfiability */
status = msat_solve(env);
assert(status == MSAT_UNSAT);
printf("Environment is inconsistent, retracting constraint %s\n", s);
/* retract the assertion and try again with another one */
res = msat_pop_backtrack_point(env);
assert(res == 0);
res = msat_push_backtrack_point(env);
assert(res == 0);
formula = msat_from_string(env, "(= v5 v8)");
assert(!MSAT_ERROR_TERM(formula));
res = msat_assert_formula(env, formula);
assert(res == 0);
msat_free(s);
s = msat_term_repr(formula);
assert(s);
printf("Added constraint: %s\n", s);
msat_free(s);
status = msat_solve(env);
assert(status == MSAT_SAT);
printf("Environment is now consistent, getting the model...\n");
/* display the model */
print_model(env);
msat_destroy_env(env);
msat_destroy_config(cfg);
printf("\nExample 1 done\n");
}
/*
* this example shows how to generate an interpolant for the following pair of
* formulas:
* A = (and (= (+ (f x1) x2) x3) (= (+ (f y1) y2) y3) (<= y1 x1))
* B = (and (= x2 (g b)) (= y2 (g b)) (<= x1 y1) (< x3 y3))
*/
static void example_interpolation1()
{
msat_config cfg;
msat_env env;
msat_term formula;
const char *vars[] = {"x1", "x2", "x3", "y1", "y2", "y3", "b"};
const char *ufs[] = {"f", "g"};
unsigned int i;
int res, group_a, group_b;
msat_type rat_tp, func_tp;
msat_type paramtps[1];
printf("\nInterpolation example\n");
cfg = msat_create_config();
/* enable interpolation support */
msat_set_option(cfg, "interpolation", "true");
env = msat_create_env(cfg);
assert(!MSAT_ERROR_ENV(env));
/* the configuration can be deleted as soon as the evironment has been
* created */
msat_destroy_config(cfg);
rat_tp = msat_get_rational_type(env);
paramtps[0] = rat_tp;
func_tp = msat_get_function_type(env, paramtps, 1, rat_tp);
/* declare variables/functions */
for (i = 0; i < sizeof(vars)/sizeof(vars[0]); ++i) {
msat_decl d = msat_declare_function(env, vars[i], rat_tp);
assert(!MSAT_ERROR_DECL(d));
}
for (i = 0; i < sizeof(ufs)/sizeof(ufs[0]); ++i) {
msat_decl d = msat_declare_function(env, ufs[i], func_tp);
assert(!MSAT_ERROR_DECL(d));
}
/* now create the interpolation groups representing the two formulas A and
* B */
group_a = msat_create_itp_group(env);
group_b = msat_create_itp_group(env);
assert(group_a != -1 && group_b != -1);
/* create and assert formula A */
formula = msat_from_string(
env, "(and (= (+ (f x1) x2) x3) (= (+ (f y1) y2) y3) (<= y1 x1))");
assert(!MSAT_ERROR_TERM(formula));
/* tell MathSAT that all subsequent formulas belong to group A */
res = msat_set_itp_group(env, group_a);
assert(res == 0);
res = msat_assert_formula(env, formula);
assert(res == 0);
{
char *s = msat_term_repr(formula);
assert(s);
printf("Asserted formula A (in group %d): %s\n", group_a, s);
msat_free(s);
}
/* create and assert formula B */
formula = msat_from_string(
env, "(and (= x2 (g b)) (= y2 (g b)) (<= x1 y1) (< x3 y3))");
assert(!MSAT_ERROR_TERM(formula));
/* tell MathSAT that all subsequent formulas belong to group B */
res = msat_set_itp_group(env, group_b);
assert(res == 0);
res = msat_assert_formula(env, formula);
assert(res == 0);
{
char *s = msat_term_repr(formula);
assert(s);
printf("Asserted formula B (in group %d): %s\n", group_b, s);
msat_free(s);
}
if (msat_solve(env) == MSAT_UNSAT) {
int groups_of_a[1];
msat_term interpolant;
char *s;
groups_of_a[0] = group_a;
interpolant = msat_get_interpolant(env, groups_of_a, 1);
assert(!MSAT_ERROR_TERM(interpolant));
s = msat_term_repr(interpolant);
assert(s);
printf("\nOK, the interpolant is: %s\n", s);
msat_free(s);
} else {
assert(0 && "should not happen!");
}
msat_destroy_env(env);
printf("\nInterpolation example 1 done\n");
}
static void example_interpolation2()
{
msat_config cfg;
const char *a_part;
const char *b_part_1;
const char *b_part_2;
msat_env env;
msat_term fa, fb1, fb2, itp;
msat_result res;
int ia, ib1, ib2;
char *s;
int ga[1];
cfg = msat_create_config();
msat_set_option(cfg, "interpolation", "true");
a_part =
"(declare-fun x () Bool)"
"(declare-fun y () Bool)"
"(declare-fun z () Bool)"
"(assert (and (or x y) (or (not y) x) (or (not x) z)))";
b_part_1 =
"(declare-fun z () Bool)"
"(declare-fun w () Bool)"
"(declare-fun v () Bool)"
"(assert (and (or w v (not z)) (or (not w) v) (not v)))";
b_part_2 =
"(declare-fun z () Bool)"
"(declare-fun x () Bool)"
"(declare-fun v () Bool)"
"(assert (and (or v (not z) (not x)) (or (not v) (not z))))";
env = msat_create_env(cfg);
fa = msat_from_smtlib2(env, a_part);
fb1 = msat_from_smtlib2(env, b_part_1);
ia = msat_create_itp_group(env);
msat_set_itp_group(env, ia);
msat_assert_formula(env, fa);
msat_push_backtrack_point(env);
ib1 = msat_create_itp_group(env);
msat_set_itp_group(env, ib1);
msat_assert_formula(env, fb1);
res = msat_solve(env);
assert(res == MSAT_UNSAT);
ga[0] = ia;
itp = msat_get_interpolant(env, ga, 1);
assert(!MSAT_ERROR_TERM(itp));
s = msat_to_smtlib2(env, itp);
printf("Got interpolant 1:\n%s\n", s);
msat_free(s);
msat_pop_backtrack_point(env);
msat_push_backtrack_point(env);
fb2 = msat_from_smtlib2(env, b_part_2);
ib2 = msat_create_itp_group(env);
msat_set_itp_group(env, ib2);
msat_assert_formula(env, fb2);
res = msat_solve(env);
assert(res == MSAT_UNSAT);
itp = msat_get_interpolant(env, ga, 1);
assert(!MSAT_ERROR_TERM(itp));
s = msat_to_smtlib2(env, itp);
printf("Got interpolant 2:\n%s\n", s);
msat_free(s);
msat_destroy_env(env);
msat_destroy_config(cfg);
printf("Interpolation example 2 done\n");
}
void example_unsat_core()
{
msat_config cfg;
msat_env env;
msat_decl x, y;
msat_term a, b, c, t;
msat_result res;
msat_term *core;
size_t i, core_size;
char *s;
cfg = msat_create_config();
/* enable unsat core generation */
msat_set_option(cfg, "unsat_core_generation", "1");
env = msat_create_env(cfg);
msat_destroy_config(cfg);
x = msat_declare_function(env, "x", msat_get_rational_type(env));
y = msat_declare_function(env, "y", msat_get_rational_type(env));
a = msat_from_string(env, "(not (> x 2))");
b = msat_from_string(env, "(> x 3)");
c = msat_from_string(env, "(> (+ x y) 0)");
/* compute an unsat core as a subset of the asserted formulas */
/* first, we assert the three constraints individually */
msat_assert_formula(env, a);
s = msat_term_repr(a);
printf("asserted: %s, id: %d\n", s, msat_term_id(a));
msat_free(s);
msat_assert_formula(env, b);
s = msat_term_repr(b);
printf("asserted: %s, id: %d\n", s, msat_term_id(b));
msat_free(s);
msat_assert_formula(env, c);
s = msat_term_repr(c);
printf("asserted: %s, id: %d\n", s, msat_term_id(c));
msat_free(s);
res = msat_solve(env);
assert(res == MSAT_UNSAT);
/* get the unsat core */
core = msat_get_unsat_core(env, &core;_size);
if (core == NULL) {
printf("error in computing the unsat core\n");
} else {
printf("the unsat core is:\n");
for (i = 0; i < core_size; ++i) {
t = core[i];
s = msat_term_repr(t);
printf(" %s, id: %d\n", s, msat_term_id(t));
msat_free(s);
}
msat_free(core);
}
msat_destroy_env(env);
printf("Unsat core example done\n");
}
|