Commits

Pierre Carbonnelle committed 669dc6e

Do not recreate existing atoms. Add HeadLiteral class.

Comments (0)

Files changed (2)

pyDatalog/pyDatalog.py

     try:
         locals_ = stack[1][0].f_locals
         for arg in set(args + ('_sum','_min', '_max', '_len')):
-            if arg in locals_ and not isinstance(locals_[arg], (pyParser.Symbol, pyDatalog.Variable)):
-                raise BaseException("Name conflict.  Can't redefine %s as atom" % arg)
-            if arg[0] not in string.ascii_uppercase:
-                locals_[arg] = pyParser.Symbol(arg)
+            if arg in locals_: 
+                assert isinstance(locals_[arg], (pyParser.Symbol, pyDatalog.Variable)), \
+                    "Name conflict.  Can't redefine %s as atom" % arg
             else:
-                locals_[arg] = pyDatalog.Variable()    
+                if arg[0] not in string.ascii_uppercase:
+                    locals_[arg] = pyParser.Symbol(arg)
+                else:
+                    locals_[arg] = pyDatalog.Variable()    
     finally:
         del stack
 

pyDatalog/pyParser.py

 
     @classmethod
     def make(cls, predicate_name, terms, prearity=None, aggregate=None):
-        if False: #TODO should test predicate_name[-1]=='!' instead, but  python uses __ge__ instead of __le__ !
-            return Literal(predicate_name, terms, prearity, aggregate)
+        if predicate_name[-1]=='!':
+            return HeadLiteral(predicate_name, terms, prearity, aggregate)
         else:
             return Query(predicate_name, terms, prearity, aggregate)
     
         " head <= body"
         if isinstance(body, Literal):
             newBody = body.pre_calculations & body
-            if isinstance(body, Literal) and body.predicate_name[-1]=='!':
+            if isinstance(body, HeadLiteral):
                 raise pyDatalog.DatalogError("Aggregation cannot appear in the body of a clause", None, None)
         else:
             if not isinstance(body, Body):
                 raise pyDatalog.DatalogError("Invalid body for clause", None, None)
             newBody = Body()
             for literal in body.literals:
-                if isinstance(literal, Literal) and literal.predicate_name[-1]=='!':
+                if isinstance(literal, HeadLiteral):
                     raise pyDatalog.DatalogError("Aggregation cannot appear in the body of a clause", None, None)
                 newBody = newBody & literal.pre_calculations & literal
         result = pyDatalog.add_clause(self, newBody)
             raise pyDatalog.DatalogError("Can't create clause", None, None)
         return result
 
+class HeadLiteral(Literal):
+    """ represents literals that can be used only in head of clauses, i.e. literals with aggregate function"""
+    pass
+
 class Query(Literal, LazyListOfList):
     """
     represents a literal that can be queried (thus excludes aggregate literals)