176 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <SWI-Stream.h>
 | |
| #include <SWI-Prolog.h>
 | |
| #include <stdio.h>
 | |
| #include <assert.h>
 | |
| 
 | |
| #include "Solver.h"
 | |
| 
 | |
| #define val(i) ((s->model[i] != l_Undef) ? ((s->model[i]==l_True)? i+1:-1*(i+1)):0)
 | |
| 
 | |
| Solver      *s = NULL;
 | |
| 
 | |
| 
 | |
| extern "C" foreign_t minisat_new_solver()
 | |
| {
 | |
|   s = new Solver;
 | |
|   PL_succeed;
 | |
| }
 | |
| 
 | |
| 
 | |
| extern "C"  foreign_t minisat_delete_solver()
 | |
| {
 | |
|     if (s) {
 | |
|       delete s;
 | |
|       s = NULL;
 | |
|     }
 | |
|     PL_succeed;
 | |
| }
 | |
| 
 | |
| static inline Lit pl2lit(term_t pl_literal)
 | |
| {
 | |
|   int pl_lit_int, var;
 | |
|   PL_get_integer(pl_literal,&pl_lit_int);
 | |
|   var = abs(pl_lit_int)-1;
 | |
|   while (var >= s->nVars()) s->newVar();
 | |
|   return (pl_lit_int > 0) ? Lit(var) : ~Lit(var);
 | |
| }
 | |
| 
 | |
| 
 | |
| extern "C" foreign_t minisat_set_minvars(term_t l)
 | |
| {
 | |
|     term_t head = PL_new_term_ref();      /* variable for the elements */
 | |
|     term_t list = PL_copy_term_ref(l);    /* copy as we need to write */
 | |
|     
 | |
|     vec<Lit> lits;
 | |
| 
 | |
|     while( PL_get_list(list, head, list) ) {
 | |
|       lits.push( pl2lit(head) );
 | |
|     }
 | |
| 
 | |
|     assert(PL_get_nil(list));
 | |
| 
 | |
|     if (s->setminVars(lits)) PL_succeed; else PL_fail;
 | |
| }
 | |
| 
 | |
| extern "C" foreign_t minisat_add_clause(term_t l)
 | |
| {
 | |
|     term_t head = PL_new_term_ref();      /* variable for the elements */
 | |
|     term_t list = PL_copy_term_ref(l);    /* copy as we need to write */
 | |
|     
 | |
|     vec<Lit> lits;
 | |
| 
 | |
|     while( PL_get_list(list, head, list) ) {
 | |
|       lits.push( pl2lit(head) );
 | |
|     }
 | |
| 
 | |
|     assert(PL_get_nil(list));
 | |
|     
 | |
|     if (s->addClause(lits)) PL_succeed; else PL_fail;
 | |
| }
 | |
| 
 | |
| 
 | |
| extern "C" foreign_t minisat_solve(term_t assum) {
 | |
| 
 | |
|     term_t head = PL_new_term_ref();      /* variable for the elements */
 | |
|     term_t list = PL_copy_term_ref(assum);    /* copy as we need to write */
 | |
|   
 | |
|     vec<Lit> assumptions;
 | |
| 
 | |
|     while( PL_get_list(list, head, list) ) {
 | |
|       assumptions.push( pl2lit(head) );
 | |
|     }
 | |
| 
 | |
|     if (s->solve(assumptions)) PL_succeed; else PL_fail;
 | |
| }
 | |
| 
 | |
| 
 | |
| extern "C" foreign_t minisat_get_var_assignment(term_t var, term_t res)
 | |
| {
 | |
|   int i;
 | |
| 
 | |
|   PL_get_integer(var,&i);
 | |
|   i--;
 | |
| 
 | |
|   if (i < s->nVars()) {
 | |
|     term_t a = PL_new_term_ref();      /* variable for the elements */  
 | |
|     PL_put_integer(a, val(i));
 | |
|     return PL_unify(a,res);
 | |
|   } else {
 | |
|     PL_fail;
 | |
|   }
 | |
| }
 | |
| 
 | |
| extern "C" foreign_t minisat_nvars(term_t res)
 | |
| {
 | |
|   term_t a = PL_new_term_ref();      /* variable for the elements */  
 | |
|   PL_put_integer(a, s->nVars());
 | |
|   return PL_unify(a,res);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| //=============================================================================
 | |
| static const PL_extension predicates[] =
 | |
|     {
 | |
|         //
 | |
|         //  { "name", arity, function, PL_FA_<flags> },
 | |
|         //
 | |
| 
 | |
|       { "minisat_new_solver",         0, (void*)minisat_new_solver,         0 },
 | |
|       { "minisat_delete_solver",      0, (void*)minisat_delete_solver,      0 },
 | |
|       { "minisat_add_clause",         1, (void*)minisat_add_clause,         0 },
 | |
|       { "minisat_solve",              1, (void*)minisat_solve,              0 },
 | |
|       { "minisat_get_var_assignment", 2, (void*)minisat_get_var_assignment, 0 },
 | |
|       { "minisat_nvars",              1, (void*)minisat_nvars,              0 },
 | |
|       { NULL,                         0, NULL,                              0 }    // terminating line
 | |
|     };
 | |
| 
 | |
| //-----------------------------------------------------------------------------
 | |
| extern "C" install_t install()
 | |
| {
 | |
|     //Sdprintf("%% SWI-Prolog interface to MiniSat");
 | |
|     //Sdprintf(" - built on ");
 | |
|     //Sdprintf(__DATE__);
 | |
|     //Sdprintf(", ");
 | |
|     //Sdprintf(__TIME__);
 | |
|     //Sdprintf(" ... ");
 | |
|     PL_register_extensions(predicates);	/* This is the only PL_ call allowed */
 | |
| 					/* before PL_initialise().  It */
 | |
| 					/* ensures the foreign predicates */
 | |
| 					/* are available before loading */
 | |
| 					/* Prolog code */
 | |
| 
 | |
|     //Sdprintf("OK\n");
 | |
| }
 | |
| 
 | |
| //-----------------------------------------------------------------------------
 | |
| // This part is for compiling into a standalone executable
 | |
| 
 | |
| #ifdef READLINE
 | |
| static void install_readline(int argc, char**argv)
 | |
| {
 | |
|     PL_install_readline();
 | |
| }
 | |
| #endif
 | |
| 
 | |
| int main(int argc, char **argv)
 | |
| {
 | |
| 
 | |
| #ifdef READLINE
 | |
|     PL_initialise_hook(install_readline);
 | |
| #endif
 | |
| 
 | |
|     install();
 | |
|     if ( !PL_initialise(argc, argv) )
 | |
| 	PL_halt(1);
 | |
|     
 | |
|     PL_halt(PL_toplevel() ? 0 : 1);
 | |
|     
 | |
|     return 0;
 | |
| }
 |