Commits

Pierre Carbonnelle committed 40d85cd

use create_atoms in queens.py example.
Fix issue with stringification of in-line comparison.
add __init__.py to examples directory.

Comments (0)

Files changed (4)

pyDatalog/examples/__init__.py

+'''
+Created on Sep 26, 2012
+
+@author: pcarbonn
+'''

pyDatalog/examples/queens.py

 from pyDatalog import pyDatalog
 import time
 
-pyDatalog.clear()
-@pyDatalog.program()
-def _():
-    queens0(X0) <= (X0 in range(8))
+pyDatalog.create_atoms('N,X0,X1,X2,X3,X4,X5,X6,X7')
+pyDatalog.create_atoms('ok,queens0,queens1,queens2,queens3,queens4,queens5,queens6,queens7')
 
-    # when is it ok to have a queen in row X1 and another in row X2, separated by N columns
-    # this is memoized !
-    ok(X1, N, X2) <= (X1!=X2) & (X1!= X2+N) & (X1!=X2-N)
-    
-    queens1(X0,X1) <= queens0(X0) & queens0(X1) & ok(X1,1,X0)
+queens0(X0) <= (X0._in(range(8)))
 
-    queens2(X0,X1,X2) <= queens1(X0,X1) & queens1(X1,X2) & ok(X0,2,X2)
+# when is it ok to have a queen in row X1 and another in row X2, separated by N columns
+# this is memoized !
+ok(X1, N, X2) <= (X1!=X2) & (X1!= X2+N) & (X1!=X2-N)
 
-    queens3(X0,X1,X2,X3) <= queens2(X0,X1,X2) & queens2(X1,X2,X3) & ok(X0,3,X3)
+queens1(X0,X1) <= queens0(X0) & queens0(X1) & ok(X1,1,X0)
 
-    queens4(X0,X1,X2,X3,X4) <= queens3(X0,X1,X2,X3) & queens3(X1,X2,X3,X4) & ok(X0,4,X4)
+queens2(X0,X1,X2) <= queens1(X0,X1) & queens1(X1,X2) & ok(X0,2,X2)
 
-    queens5(X0,X1,X2,X3,X4,X5) <= queens4(X0,X1,X2,X3,X4) & queens4(X1,X2,X3,X4,X5) & ok(X0,5,X5)
+queens3(X0,X1,X2,X3) <= queens2(X0,X1,X2) & queens2(X1,X2,X3) & ok(X0,3,X3)
 
-    queens6(X0,X1,X2,X3,X4,X5,X6) <= queens5(X0,X1,X2,X3,X4,X5) & queens5(X1,X2,X3,X4,X5,X6) & ok(X0,6,X6)
-    # counting is 0-based, so this is actually the 8-queens solution
-    queens7(X0,X1,X2,X3,X4,X5,X6,X7) <= queens6(X0,X1,X2,X3,X4,X5,X6) & queens6(X1,X2,X3,X4,X5,X6,X7) & ok(X0,7,X7)
+queens4(X0,X1,X2,X3,X4) <= queens3(X0,X1,X2,X3) & queens3(X1,X2,X3,X4) & ok(X0,4,X4)
+
+queens5(X0,X1,X2,X3,X4,X5) <= queens4(X0,X1,X2,X3,X4) & queens4(X1,X2,X3,X4,X5) & ok(X0,5,X5)
+
+queens6(X0,X1,X2,X3,X4,X5,X6) <= queens5(X0,X1,X2,X3,X4,X5) & queens5(X1,X2,X3,X4,X5,X6) & ok(X0,6,X6)
+# counting is 0-based, so this is actually the 8-queens solution
+queens7(X0,X1,X2,X3,X4,X5,X6,X7) <= queens6(X0,X1,X2,X3,X4,X5,X6) & queens6(X1,X2,X3,X4,X5,X6,X7) & ok(X0,7,X7)
 
 # counting is 0-based, so this is actually the 8-queens solution
 print(pyDatalog.ask("queens7(X0,X1,X2,X3,X4,X5,X6,X7)"))

pyDatalog/pyDatalog.py

     stack = inspect.stack()
     try:
         locals_ = stack[1][0].f_locals
-        for arg in set(args + ('_sum','_min', '_max', '_len')):
+        args = [arg.split(',') for arg in args]
+        args = [arg.strip() for argl in args for arg in argl]
+        for arg in set(args + ['_sum','_min', '_max', '_len']):
             if arg in locals_: 
                 assert isinstance(locals_[arg], (pyParser.Symbol, pyDatalog.Variable)), \
                     "Name conflict.  Can't redefine %s as atom" % arg

pyDatalog/pyParser.py

         self.symbol = Function.newSymbol()
         self.dummy_variable_name = '_pyD_X%i' % Function.Counter
     
+    @property
+    def _pyD_name(self):
+        return str(self)
+    
     def __eq__(self, other):
         return Literal.make_for_comparison(self, '==', other)
     
         self.lhs = _convert(lhs)
         self.rhs = _convert(rhs)
         
+    @property
+    def _pyD_name(self):
+        return str(self)
+    
     def _variables(self):
         temp = self.lhs._variables()
         temp.update(self.rhs._variables())
         return pyEngine.make_expression(self.operator, self.lhs.lua_expr(variables), self.rhs.lua_expr(variables))
     
     def __str__(self):
-        return '(' + str(self.lhs) + self.operator + str(self.rhs) + ')'
+        return '(' + str(self.lhs._pyD_name) + self.operator + str(self.rhs._pyD_name) + ')'
 
 class Lambda(Expression):
     """represents a lambda function, used in expressions"""
         self.operator = '<lambda>'
         self.lambda_object = other
         
+    @property
+    def _pyD_name(self):
+        return str(self)
+    
     def _variables(self):
         return dict([ [var, Symbol(var)] for var in getattr(self.lambda_object,func_code).co_varnames])
     
             else: 
                 return Literal.make(self.name + operator, list(self.keys) + [other], prearity=len(self.keys))
         else:
-            name = '=' + str(self) + operator + str(other)
             if other is None or isinstance(other, (int, six.string_types, list, tuple, xrange)):
+                name = '=' + self._pyD_name + operator + str(other)
                 literal = Literal.make(name, [self])
                 expr = pyEngine.make_operand('constant', other)
             else: 
-                if not isinstance(other, (Symbol, Expression)):
+                if not isinstance(other, Expression):
                     raise pyDatalog.DatalogError("Syntax error: Symbol or Expression expected", None, None)
+                name = '=' + self._pyD_name + operator + other._pyD_name
                 literal = Literal.make(name, [self] + list(other._variables().values()))
                 expr = other.lua_expr(list(self._variables().keys())+list(other._variables().keys()))
                 literal.pre_calculations = other._precalculation()