First try on a (ruby based) policy engine
authorKlaus Kaempf <kkaempf@suse.de>
Thu, 1 Nov 2007 14:18:46 +0000 (14:18 +0000)
committerKlaus Kaempf <kkaempf@suse.de>
Thu, 1 Nov 2007 14:18:46 +0000 (14:18 +0000)
- src/policy.h: generic policy interface
- src/policy-ruby.c: ruby implementation of policy interface
- testsuite/satsolver_policy.rb: sample policy as ruby code

CMakeLists.txt
src/CMakeLists.txt
src/policy-ruby.c [new file with mode: 0644]
src/policy.h [new file with mode: 0644]
src/solver.c

index ef809a0..fb1b0b1 100644 (file)
@@ -22,6 +22,7 @@ INCLUDE( ${CMAKE_SOURCE_DIR}/VERSION.cmake )
 
 FIND_PACKAGE(Db43 REQUIRED)
 FIND_PACKAGE(EXPAT REQUIRED)
+FIND_PACKAGE(Ruby REQUIRED)
 
 SET( PACKAGE "satsolver" )
 SET( VERSION "${LIBSATSOLVER_MAJOR}.${LIBSATSOLVER_MINOR}.${LIBSATSOLVER_PATCH}" )
index 6866a8b..9256bb1 100644 (file)
@@ -1,10 +1,13 @@
 
 SET(libsatsolver_SRCS bitmap.c  poolarch.c  poolvendor.c  poolid.c
-solver.c  repo_solv.c evr.c pool.c queue.c   repo.c  util.c)
+solver.c  repo_solv.c evr.c pool.c queue.c   repo.c  util.c
+policy-ruby.c)
 
 ADD_LIBRARY(satsolver STATIC ${libsatsolver_SRCS})
 
-SET(libsatsolver_HEADERS bitmap.h evr.h hash.h poolarch.h poolvendor.h pool.h poolid.h pooltypes.h queue.h solvable.h solver.h repo.h repo_solv.h util.h )
+SET(libsatsolver_HEADERS bitmap.h evr.h hash.h policy.h poolarch.h poolvendor.h pool.h poolid.h pooltypes.h queue.h solvable.h solver.h repo.h repo_solv.h util.h )
+
+SET( CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -g -O3 -Wall -I${RUBY_INCLUDE_PATH}" )
 
 INSTALL(  FILES ${libsatsolver_HEADERS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/satsolver" )
 INSTALL(TARGETS satsolver LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR})
diff --git a/src/policy-ruby.c b/src/policy-ruby.c
new file mode 100644 (file)
index 0000000..566dc39
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Ruby policy backend for SAT solver
+ * 
+ */
+#include <stdio.h>
+#include "policy.h"
+
+#include "ruby.h"
+
+static const Pool *pool;
+static VALUE cPolicy;
+
+int
+policy_init( const Pool *p )
+{
+  ruby_init();
+  ruby_init_loadpath();
+  rb_set_safe_level(0); //FIXME
+
+  /* give the ruby code a name */
+  ruby_script("satsolver_policy");
+
+  cPolicy = rb_define_class( "SatPolicy", rb_cObject );
+
+  /* load the policy implementation */
+  rb_require( "satsolver_policy" );
+  
+  pool = p;
+
+  return 0;
+}
+
+
+int
+policy_exit( void )
+{
+  pool = NULL;
+  return 0;
+}
+
+/*-----------------------------------------------*/
+int
+policy_printrules( void )
+{
+  static VALUE id = Qnil;
+  
+  /* check if ruby implementation available */
+  if (NIL_P( id )) {
+    id = rb_intern( "printrules" );
+    if (rb_respond_to( cPolicy, id ) == Qfalse) {
+      id = Qfalse;
+    }
+  }
+  
+  /* call ruby, if available */
+  if (RTEST( id )) {
+    return RTEST( rb_funcall( cPolicy, id, 0 ) );
+  }
+
+  /* default: false */
+  return 0;
+}
diff --git a/src/policy.h b/src/policy.h
new file mode 100644 (file)
index 0000000..a00df94
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Generic policy interface for SAT solver
+ * 
+ */
+
+#include "solver.h"
+
+int policy_printrules( void );
+
+int policy_init( const Pool *pool );
+int policy_exit( void );
index 0ce65d2..b97832a 100644 (file)
@@ -16,6 +16,8 @@
 #include "evr.h"
 #include "poolvendor.h"
 
+#include "policy.h"
+
 #define RULES_BLOCK 63
 
 static Pool *prune_best_version_arch_sortcmp_data;
@@ -1872,6 +1874,8 @@ solver_create(Pool *pool, Repo *installed)
   memset(solv->rules, 0, sizeof(Rule));
   solv->nrules = 1;
 
+  policy_init( pool );
+
   return solv;
 }
 
@@ -1883,6 +1887,8 @@ solver_create(Pool *pool, Repo *installed)
 void
 solver_free(Solver *solv)
 {
+  policy_exit();
+
   queue_free(&solv->ruletojob);
   queue_free(&solv->decisionq);
   queue_free(&solv->decisionq_why);
@@ -1924,16 +1930,15 @@ run_solver(Solver *solv, int disablerules, int doweak)
   Pool *pool = solv->pool;
   Id p, *dp;
 
-#if 0
-  printf("number of rules: %d\n", solv->nrules);
+if (policy_printrules())
 {
+  printf("number of rules: %d\n", solv->nrules);
   int i;
   for (i = 0; i < solv->nrules; i++)
     {
       printrule(solv, solv->rules + i);
     }
 }
-#endif
 
   /* all new rules are learnt after this point */
   solv->learntrules = solv->nrules;
@@ -2973,8 +2978,7 @@ solve(Solver *solv, Queue *job)
                  FOR_PROVIDES(p, pp, sug)
                    MAPSET(&solv->suggestsmap, p);
                }
-           }
-       }
+           }   }
       for (i = 1; i < pool->nsolvables; i++)
        {
          if (solv->decisionmap[i] != 0)