This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/bee/yap-interface.cc.cmake
Vitor Santos Costa 16015bd8e6 bee
2019-04-22 12:15:21 +01:00

260 lines
5.6 KiB
CMake

#include <YapInterface.h>
#include "Solver.h"
namespace @Solver@ {
#define val(i) YAP_MkIntTerm((s->model[i] != l_Undef) ? ((s->model[i]==l_True)? i+1:-1*(i+1)):0)
Solver *s = NULL;
int seed=0;
vec<Solver*> cache_slvrs;
extern "C" bool @solver@_default_seed()
{
seed = YAP_IntOfTerm(YAP_ARG1);
return true;
}
extern "C" bool @solver@_new_solver()
{
if (s) {
fprintf(stderr,"%% Warning: @solver@_new_solver deleted existing solver !\n");
delete s;
s = NULL;
}
s = new Solver;
if (seed != 0) {
#if CRYPTOMINISAT
s->setSeed(seed);
#else
s->random_seed = seed;
#endif
}
return true;
}
extern "C" bool @solver@_delete_solver()
{
if (s) {
delete s;
s = NULL;
} else {
fprintf(stderr,"%% Warning: @solver@_delete_solver didn't had a solver to delete !\n");
}
return true;
}
extern "C" bool @solver@_cache_push_solver()
{
if (s) {
cache_slvrs.push(s);
s = NULL;
return true;
} else {
fprintf(stderr,"%% Error: @solver@_cache_push_solver failed since no active SAT solver !\n");
return false;
}
}
extern "C" bool @solver@_cache_pop_solver()
{
if (cache_slvrs.size() == 0) {
fprintf(stderr,"%% Error: @solver@_cache_pop_solver failed since no cached SAT solver !\n");
return false;
}
if (s) {
fprintf(stderr,"%% Warning: @solver@_cache_pop_solver deleted existing solver !\n");
delete s;
s = NULL;
}
s = cache_slvrs.last();
cache_slvrs.pop();
return true;
}
static inline Lit pl2lit(YAP_Term t)
{
int pl_lit_int, var;
pl_lit_int = YAP_IntOfTerm(YAP_ARG1);
var = abs(pl_lit_int)-1;
while (var >= s->nVars()) s->newVar();
#if CRYPTOMINISAT
return Lit(var,!(pl_lit_int > 0));
#else
return mkLit(var,!(pl_lit_int > 0));
#endif
}
extern "C" bool @solver@_add_clause()
{
YAP_Term head; /* variable for the elements */
YAP_Term list = YAP_ARG1; /* copy as we need to write */
vec<Lit> lits;
while( YAP_IsPairTerm(list)) {
head = YAP_HeadOfTerm(list);
lits.push( pl2lit(head) );
list = YAP_TailOfTerm( list);
}
if (list != YAP_TermNil())
return false;
//assert(PL_get_nil(list));
return s->addClause(lits);
}
extern "C" bool @solver@_solve() {
#if CRYPTOMINISAT
lbool x=s->solve();
return x==l_True;
#else
return s->solve();
#endif
}
extern "C" bool @solver@_solve_assumptions() {
YAP_Term head; /* variable for the elements */
YAP_Term list = YAP_ARG1; /* copy as we need to write */
vec<Lit> lits;
while( YAP_IsPairTerm(list)) {
head = YAP_HeadOfTerm(list);
lits.push( pl2lit(head) );
list = YAP_TailOfTerm( list);
}
if (list != YAP_TermNil())
return false;
// assert(PL_get_nil(list));
#if CRYPTOMINISAT
lbool rc = s->solve();
return rc == l_True;
#else
return s->solve();
#endif
}
extern "C" bool @solver@_get_var_assignment()
{
int i;
i = YAP_IntOfTerm(YAP_ARG1);
i--;
if (i < s->nVars()) {
return YAP_Unify(YAP_ARG2,val(i));
} else {
return false;
}
}
extern "C" bool @solver@_get_model()
{
YAP_Term l = YAP_TermNil();
int i=s->nVars();
while( --i >= 0 ) {
l = YAP_MkPairTerm( l, val(i) );
}
return YAP_Unify(YAP_ARG1,l);
}
extern "C" bool @solver@_assign_model()
{
YAP_Term asgnList = YAP_ARG1; /* variable for the elements */
int indx=0;
while( YAP_IsPairTerm(asgnList) ) {
YAP_Term asgnVar = YAP_HeadOfTerm(asgnList);
if(s->model[indx]==l_True)
YAP_Unify(YAP_MkIntTerm(1),asgnVar);
else
YAP_Unify(YAP_MkIntTerm(-1),asgnVar);
indx++;
asgnList = YAP_TailOfTerm(asgnList);
}
return true;
}
extern "C" bool @solver@_nvars()
{
return YAP_Unify(YAP_ARG1,YAP_MkIntTerm(s->nVars()));
}
} // @solver@
//=============================================================================
typedef struct {
const char *name;
int arity;
YAP_UserCPred f;
int opts;
} extension;
static extension predicates[] =
{
//
// { "name", arity, function, PL_FA_<flags> },
//
{ "@solver@_new_solver", 0, @Solver@::@solver@_new_solver, 0 },
{ "@solver@_delete_solver", 0, @Solver@::@solver@_delete_solver, 0 },
{ "@solver@_cache_push_solver", 0, @Solver@::@solver@_cache_push_solver, 0 },
{ "@solver@_cache_pop_solver", 0, @Solver@::@solver@_cache_pop_solver, 0 },
{ "@solver@_add_clause", 1, @Solver@::@solver@_add_clause, 0 },
{ "@solver@_solve", 0, @Solver@::@solver@_solve, 0 },
{ "@solver@_solve_assumptions", 1, @Solver@::@solver@_solve_assumptions, 0 },
{ "@solver@_get_var_assignment", 2, @Solver@::@solver@_get_var_assignment, 0 },
{ "@solver@_get_model", 1, @Solver@::@solver@_get_model, 0 },
{ "@solver@_assign_model", 1, @Solver@::@solver@_assign_model, 0 },
{ "@solver@_nvars", 1, @Solver@::@solver@_nvars, 0 },
{ "@solver@_default_seed", 1, @Solver@::@solver@_default_seed, 0 },
{ nullptr, 0, nullptr, 0 } // terminating line
};
//-----------------------------------------------------------------------------
extern "C" bool install()
{
extension *pt = predicates;
fprintf(stderr,"%% Yap interface to MiniSAT v2.0.2 ... ");
while (pt->name) {
YAP_UserCPredicate(pt->name, pt->f, pt->arity);
}
/* This is the only PL_ call allowed */
/* before PL_initialise(). It */
/* ensures the foreign predicates */
/* are available before loading */
/* Prolog code */
fprintf(stderr,"OK\n");
return true;
}