Solution
========
a = [1, 2].
+b = true.
+c = true.
+d = false.
+things = [1, [2, 2], [3, 4]].
+
+d/1
+===
+d(2) = true.
+d(4) = true.
f/1
===
f([1, 2]) = true.
+foo/1
+=====
+foo("a") = true.
+
goal/1
======
goal([2]) = true.
+goo/1
+=====
+goo([1, 2]) = true.
+
a := [1,2].
goal(X) := f([1|X]).
+
+% structured term, sould be true
+b := &f("a") in [1,2,&f("a"),3].
+
+% should be true
+c := 2 in [1,2,3].
+
+% should be false
+d := 4 in [1,2,3].
+
+% simpler iteration of a complex list
+things set= X for X in [1,[2,2],[3,4]].
+
+% unpack structure requiring a check
+d(&X) := true for [X,X] in [1,[2,2],[3,4],[4,4]].
+
+% these two examples should an interesting behavior
+foo(A) := true for &f(A) in [1,2,&f("a"),3].
+
+% this one checks if the value of f(A) is in the list, (note: 1 == True, in python).
+goo(A) := true for f(A) in [1,2,&f("a"),3].
[(x^.mv_var, nuniv)]
_ -> Left True
- {-
-- XXX Argh, same as above.
_ | f == "in"
-> case is of
cmod
else Left True
_ -> Left True
- -}
_ | MA.isJust (constants (f,length is)) -> Left True
_ -> Left False
go ("abs",1) = Just $ PDBS $ call "abs" []
go ("log",_) = Just $ PDBS $ call "log" []
go ("exp",1) = Just $ PDBS $ call "exp" []
- go ("sqrt",1) = Just $ PDBS $ call "sqrt" []
- go ("getattr", _) = Just $ PDBS $ call "getattr" []
- go ("uniform", _) = Just $ PDBS $ call "uniform" []
+ go ("sqrt",1) = Just $ PDBS $ call "sqrt" []
+ go ("getattr",_) = Just $ PDBS $ call "getattr" []
+ go ("uniform",_) = Just $ PDBS $ call "uniform" []
- go ("split", _) = Just $ PDBS $ call "split" []
- go ("float", _) = Just $ PDBS $ call "float" []
- go ("int", _) = Just $ PDBS $ call "int" []
- go ("pycall", _) = Just $ PDBS $ call "pycall" []
+ go ("split",_) = Just $ PDBS $ call "split" []
+ go ("float",_) = Just $ PDBS $ call "float" []
+ go ("int",_) = Just $ PDBS $ call "int" []
+ go ("pycall",_) = Just $ PDBS $ call "pycall" []
--- go ("in",2) = Just $ PDBS $ call " in " []
+ go ("in",2) = Just $ PDBS $ infixOp " in "
go ("<=",2) = Just $ PDBS $ infixOp "<="
go ("<",2) = Just $ PDBS $ infixOp "<"
- More info in crash handler. (stack trace, repl transcript, cmd-line args,
version control info, and dyna source is enough)
- - hooks to call a crash script
-
- dyna syntax which just gets passed to the backend:
- running repl commands, loaders, post-procesors
USERS
=====
- - user-defined priorities (blocked: back-chaining)
+ - user-defined priorities
- Catch typos! Warn the user if they write a predicate that is not defined on
the LHS of a rule and it's not quoted (i.e. not some new piece of structure).
print >> out, 'because %r is %s:' % (item, _repr(val))
for e, h in es:
if h is not None:
- r = h.dyna_rule
+ r = h.rule
print >> out, ' %s\n in rule %s\n %s' % (e, r.span, r.src)
print >> out
return True
if fn == 'false/0':
return False
-
if fn == 'cons/2':
return Cons(*args)
if fn == 'nil/0':
return Nil
-
-
- # FIXME:
if fn not in self.agg_name:
# item has no aggregator (e.g purely structural stuff) -- what
# happens if we add one later?
self.new_fn(fn, None)
-
return self.chart[fn].insert(args)
# def retract_item(self, item):
agenda = self.agenda
error = self.error
while agenda:
+
item = agenda.pop_smallest()
was = item.value
+
try:
now = item.aggregator.fold()
+
except AggregatorError as e:
error[item] = ('failed to aggregate item `%r` because %s' % (item, e), [(e, None)])
- now = self.build('$error/0')
+ now = self.build('$error/0') # XXX: should go an agenda or run delete?
changed[item] = now
item.value = now
continue
except (ZeroDivisionError, TypeError, KeyboardInterrupt, NotImplementedError) as e:
error[item] = ('failed to aggregate %r' % item.aggregator, [(e, None)])
- now = self.build('$error/0')
+ now = self.build('$error/0') # XXX: should go an agenda or run delete?
changed[item] = now
item.value = now
continue
if was == now:
continue
+
was_error = False
if item in error: # clear error
was_error = True
del error[item]
+
# TODO: handle `was` and `now` at the same time to avoid the two passes.
# TODO: will need to propagate was=None when we have question mark
if was is not None and not was_error:
# if `was` is marked as an error we know it didn't propagate.
# Thus, we can skip the delete-updates.
self.update_dispatcher(item, was, delete=True)
+
item.value = now
+
if now is not None:
self.update_dispatcher(item, now, delete=False)
+
changed[item] = now
+
return changed
def update_dispatcher(self, item, val, delete):
def __repr__(self):
return '[%s]' % (', '.join(map(_repr, self.aslist)))
-# def __iter__(self):
-# for a in self.aslist:
-# if not isinstance(a, Term):
-# yield a, (None,), a
-# else:
-# yield a, (None,), a
+ def __contains__(self, x):
+ return x in self.aslist
+
+ def __iter__(self):
+ for a in self.aslist:
+ if not isinstance(a, Term):
+ yield a, (None,), a
+ else:
+ yield a, (None,), a
def __eq__(self, other):
try:
, ("%" ,[(7,PFIn AssocLeft ) ])
, ("+" ,[(6,PFIn AssocLeft ) ])
+ , ("in" ,[(4,PFIn AssocNone ) ])
+
, ("<=" ,[(4,PFIn AssocNone ) ])
, ("<" ,[(4,PFIn AssocNone ) ])
, ("=" ,[(4,PFIn AssocNone ) ])