Skip to content
Snippets Groups Projects
Commit 024751194fb7 authored by ludal's avatar ludal
Browse files

implement the last (easy) optimizations and kill dead code

parent 23162ef3b965
No related branches found
No related tags found
No related merge requests found
......@@ -22,7 +22,7 @@
except ImportError:
rql_solve = None
# Gecode solver not available
# rql_solve = None # uncomment to force using logilab-constraint
class ConstraintCSPProblem(object):
def __init__(self):
......@@ -93,14 +93,5 @@
expr = " or ".join( list(orred) )
self.add_expr( tuple(variables), expr )
class _eq(object):
def __init__(self, var, val):
self.var = var
self.val = val
def __str__(self):
return '%s == "%s"' % (self.var, self.val)
def get_vars(self, s):
s.add(self.var)
# GECODE based constraint solver
......@@ -106,4 +97,6 @@
def for_gecode(self, all_vars, all_values):
return ["eq", all_vars.index( self.var ), all_values.index(self.val) ]
_AND = "and"
_OR = "or"
_EQ = "eq"
_EQV = "eqv"
......@@ -109,14 +102,6 @@
class _eqv(object):
def __init__(self, vars):
self.vars = set(vars)
def __str__(self):
return '(' + " == ".join( str(t) for t in self.vars ) + ')'
def get_vars(self, s):
s+=self.vars
def for_gecode(self, all_vars, all_values):
l = ["eqv"]
for v in self.vars:
l.append( all_vars.index( v ) )
return l
class GecodeCSPProblem(object):
"""Builds an internal representation of the constraint
that will be passed to the rql_solve module which implements
a gecode-based solver
......@@ -122,19 +107,8 @@
class _and(object):
def __init__(self):
self.cond = []
def add(self, expr):
self.cond.append( expr )
#if expr not in self.cond:
# self.cond.append( expr )
def __str__(self):
return '(' + " and ".join( str(t) for t in self.cond ) + ')'
def get_vars(self, s):
for t in self.cond:
t.get_vars(s)
def for_gecode(self, all_vars, all_values):
l = ["and"]
for n in self.cond:
l.append( n.for_gecode(all_vars, all_values) )
return l
The internal representation is a tree builds with lists of lists
the first item of the list is the node type (_AND,_OR,_EQ,_EQV)
an example : ["and", [ "eq",0,0 ], ["or", ["eq", 1, 1], ["eq", 1, 2] ] ]
means Var(0) == Value(0) and ( Var(1)==Val(1) or Var(1) == Val(2)
......@@ -140,17 +114,9 @@
class _or(_and):
def __str__(self):
return '(' + " or ".join( str(t) for t in self.cond ) + ')'
def for_gecode(self, all_vars, all_values):
l = ["or"]
for n in self.cond:
l.append( n.for_gecode(all_vars, all_values) )
return l
# TODO: refactor/optimize:
# now that gecode solver is working we don't need the above _and/_or... classes
# we can generate the constraint tree directly as ["and", ['or',...], ... ]
# Another thing that
class GecodeCSPProblem(object):
TODO: at the moment the solver makes no type checking on the structure
of the tree thus can crash badly if something wrong is handled to it
this should not happend as the building of the tree is done internally
but it should be fixed anyways.
When fixing that we should also replace string nodes by integers
"""
def __init__(self):
self.constraints = []
......@@ -155,4 +121,4 @@
def __init__(self):
self.constraints = []
self.op = _and()
self.op = [ _AND ]
self.domains = {}
......@@ -158,6 +124,8 @@
self.domains = {}
self.variables = {}
self.values = {}
def get_output(self):
return ""
def solve(self):
# assign an integer to each var and each domain values
......@@ -159,12 +127,8 @@
def get_output(self):
return ""
def solve(self):
# assign an integer to each var and each domain values
all_values = set()
all_vars = sorted(self.domains.keys())
for values in self.domains.values():
all_values.update(values)
all_values = sorted(all_values)
constraints = self.op.for_gecode( all_vars, all_values )
all_values = range(len(self.values))
constraints = self.op #.for_gecode( all_vars, all_values )
var_domains = []
......@@ -170,9 +134,8 @@
var_domains = []
for var in all_vars:
dom = []
for val in self.domains[var]:
dom.append( all_values.index(val) )
var_domains.append( dom )
# loop through variables in increasing order of the number they have been assigned
variables = [ var_name for var_name, var_value in sorted(self.variables.items(), key=lambda item:item[1] ) ]
for var_name in variables:
var_domains.append( self.domains[var_name] )
sols = rql_solve.solve( var_domains, len(all_values), constraints )
rql_sols = []
......@@ -176,5 +139,7 @@
sols = rql_solve.solve( var_domains, len(all_values), constraints )
rql_sols = []
# values is the list of values (string) order according to the integer value they have been assigned
values = [ val_name for val_name, val_value in sorted(self.values.items(), key=lambda item:item[1] ) ]
for s in sols:
r={}
......@@ -179,8 +144,8 @@
for s in sols:
r={}
for var,val in zip(all_vars,s):
r[var] = all_values[val]
for var, val in zip(variables, s):
r[var] = values[val]
rql_sols.append(r)
return rql_sols
def add_var(self, name, values):
......@@ -183,7 +148,13 @@
rql_sols.append(r)
return rql_sols
def add_var(self, name, values):
self.domains[name] = set(values)
domain = []
var_value = self.variables.setdefault( name, len(self.variables) )
for val in values:
val_value = self.values.setdefault( val, len(self.values) )
domain.append( val_value )
self.domains[name] = domain
def and_eq( self, var, value ):
......@@ -188,7 +159,6 @@
def and_eq( self, var, value ):
eq = _eq(var, value)
self.op.add(eq)
self.op.append( [_EQ, self.variables[var], self.values[value] ] )
def equal_vars(self, varnames):
if len(varnames)>1:
......@@ -192,7 +162,7 @@
def equal_vars(self, varnames):
if len(varnames)>1:
self.op.add( _eqv(varnames) )
self.op.append( [ _EQV] + [ self.variables[v] for v in varnames ] )
def var_has_type(self, var, etype):
self.and_eq( var, etype)
......@@ -203,5 +173,5 @@
if len(etypes) == 1:
self.and_eq( var, tuple(etypes)[0] )
else:
orred = _or()
orred = [ _OR ]
for t in etypes:
......@@ -207,6 +177,6 @@
for t in etypes:
orred.add( _eq(var, t) )
self.op.add( orred )
orred.append( [ _EQ, self.variables[var], self.values[t] ] )
self.op.append( orred )
def vars_have_types(self, varnames, types):
self.equal_vars( varnames )
......@@ -214,5 +184,5 @@
self.var_has_types( var, types )
def or_and(self, equalities):
orred = _or()
orred = [ _OR ]
for orred_expr in equalities:
......@@ -218,8 +188,8 @@
for orred_expr in equalities:
anded = _and()
anded = [ _AND ]
for vars, types in orred_expr:
self.equal_vars( vars )
for t in types:
assert isinstance(t, (str,unicode))
for var in vars:
if len(types)==1:
......@@ -220,8 +190,8 @@
for vars, types in orred_expr:
self.equal_vars( vars )
for t in types:
assert isinstance(t, (str,unicode))
for var in vars:
if len(types)==1:
anded.add( _eq(var, types[0]) )
anded.append( [ _EQ, self.variables[var], self.values[types[0]] ] )
else:
......@@ -227,3 +197,3 @@
else:
or2 = _or()
or2 = [ _OR ]
for t in types:
......@@ -229,8 +199,8 @@
for t in types:
or2.add( _eq(var, t) )
anded.add( or2 )
orred.add(anded)
self.op.add(orred)
or2.append( [_EQ, self.variables[var], self.values[t] ] )
anded.append( or2 )
orred.append(anded)
self.op.append(orred)
if rql_solve is None:
CSPProblem = ConstraintCSPProblem
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment