"""
+#from debug import ultraTB2; ultraTB2.enable()
+#from debug import saverr; saverr.enable(editor=True)
+
import os, sys, math, operator
from collections import defaultdict, Counter
from utils import red, green, blue, magenta
# TODO: (functor, idx) pairs aren't nice to look at.
def pretty(item):
"Pretty print a term. Will retrieve the complete (ground) term for the chart."
+ if not isinstance(item, tuple):
+ return repr(item)
(fn, idx) = item
row = chart[fn].data[idx]
args = row[:-1]
fn = ''.join(fn.split('/')[:-1]) # drop arity from name.
- return '%s%s' % (fn, tuple(args)) # TODO: need to recurse.
+ return '%s(%s)' % (fn, ','.join(map(pretty, args)))
def prettify(x):
register.handlers = defaultdict(list)
-
def initializer(_):
def wrap(handler):
handler((fn, idx), val)
-def peel(fn, (fa, idx)):
+def peel(fn, x):
"""
Lookup `idx` in the intern table. Asserts that idx matches
`functor_arity`. Returns arguments of term as a arity-tuple of intern idxs and
constants.
"""
- assert fa == fn
+ if not isinstance(x, tuple):
+ return None
+ (fa, idx) = x
+ if fa != fn:
+ return None
return chart[fn].data[idx][:-1] # minus val
def aggregate(item):
print ' aggregate:', pretty(item), aggregator[item],
- val = 0.0
- for k,v in aggregator[item].iteritems():
- val += k*v # val*multiplicity; TODO: use correct aggregator
+ val = 0.0 # need identity element or do a "fold1"
+ for k, multiplicity in aggregator[item].iteritems():
+ assert multiplicity >= 0, "negative multiplicity: this should never happen."
+ val += k*multiplicity # val*multiplicity; TODO: use correct aggregator
print 'result:', val
return val
+def max_equals(item):
+ raise NotImplementedError
+def min_equals(item):
+ raise NotImplementedError
+def plus_equals(item):
+ raise NotImplementedError
+def times_equals(item):
+ raise NotImplementedError
+def and_equals(item):
+ raise NotImplementedError
+def or_equals(item):
+ raise NotImplementedError
+
+
+aggr = {
+ 'max=': max_equals,
+ 'min=': min_equals,
+ '+=': plus_equals,
+ '*=': times_equals,
+ '&=': and_equals,
+ '|=': or_equals,
+}
+
+
def delete(item, val):
# XXX: very ugly handling of deletion
global _delete
_delete = False
-#def papa_example():
-#
-# map(chart['rewrite/3'].insert,
-# [( "S", "S", ".", 1.),
-# ( "S", "NP", "VP", 1.),
-# ("NP", "Det", "N", 1.),
-# ("NP", "NP", "PP", 1.),
-# ("VP", "V", "NP", 1.),
-# ("VP", "VP", "PP", 1.),
-# ("PP", "P", "NP", 1.)])
-#
-# map(chart['rewrite/2'].insert,
-# [( "NP", "Papa", 1.),
-# ( "N", "caviar", 1.),
-# ( "N", "spoon", 1.),
-# ( "V", "ate", 1.),
-# ( "P", "with", 1.),
-# ("Det", "the", 1.),
-# ("Det", "a", 1.)])
-#
-# for i, word in enumerate('Papa ate the caviar with a spoon .'.split()):
-# idx = chart['phrase/3'].insert((word, i, i + 1, None))
-#
-# emit(('phrase/3', idx), 1.0)
-#
-#execfile('examples/cky.dyna.plan')
-#papa_example()
-
-
-# 'examples/papa.dyna.plan'
[dyna] = sys.argv[1:]
cmd = """ghc -isrc Dyna.Backend.Python -e 'processFile "%s"' """ % dyna
assert 0 == os.system(cmd), 'command failed:\n\t' + cmd
-
execfile(dyna + '.plan')
-
for xxx in initializer.handlers:
xxx()
phrase(X,I,K,t(X,TY)) += phrase(Y,I,K,TY) * rewrite(X,Y).
phrase(X,I,K,t(X,TY,TZ)) += phrase(Y,I,J,TY) * phrase(Z,J,K,TZ) * rewrite(X,Y,Z).
+goal(P) = phrase("S",0,*length,P).
+
+length max= word(_, I), I.
+
% grammar rules
rewrite( "S", "S", ".") += 1.
rewrite( "S", "NP", "VP") += 1.
% sentence
% "Papa at the caviar with the spoon ."
-word( "Papa", 0) .
-word( "ate", 1) .
-word( "the", 2) .
-word("caviar", 3) .
-word( "with", 4) .
-word( "a", 5) .
-word( "spoon", 6) .
-word( ".", 7) .
+word( "Papa", 0) += 1.
+word( "ate", 1) += 1.
+word( "the", 2) += 1.
+word("caviar", 3) += 1.
+word( "with", 4) += 1.
+word( "a", 5) += 1.
+word( "spoon", 6) += 1.
+word( ".", 7) += 1.
+
+% for fun, try making the above words facts instead of +=1's.
phrase(W, I, I+1, W) += 1 whenever word(W, I).
pdope :: DOpAMine -> Doc e
pdope (OPIndirEval _ _) = error "indirect evaluation not implemented"
pdope (OPAssign v val) = pretty v <+> equals <+> pretty val
-pdope (OPCheck v val) = hsep ["assert", pretty v, "==", pretty val]
+pdope (OPCheck v val) = "if" <+> pretty v <+> "!=" <+> pretty val <> ": continue"
pdope (OPGetArgsIf vs id f) =
- tupled (map pretty vs)
- <+> equals
- <+> "peel" <> (parens $ fa f vs <> comma <> pretty id)
+
+ "try:" `above` (indent 4 $
+ tupledOrUnderscore vs
+ <+> equals <> " "
+ <> "peel" <> (parens $ fa f vs <> comma <> pretty id)
+ )
+
+ `above` "except TypeError: continue" -- you'll get a "TypeError: 'NoneType' is not iterable."
+
pdope (OPBuild v vs f) = pretty v <+> equals
<+> "build" <> (parens $ fa f vs <> comma <> (sepBy "," $ map pretty vs))
pdope (OPIter o m f) =
let mo = m ++ [o] in
- "for" <+> (tupled $ filterBound mo)
+ "for" <+> (tupledOrUnderscore $ filterBound mo)
<+> "in" <+> functorIndirect "chart" f m <> pslice mo <> colon
fa f a = dquotes $ pretty f <> "/" <> (text $ show $ length a)
-pslice = brackets . sepBy ","
- . map (\x -> case x of (MF v) -> ":" ; (MB v) -> pretty v)
+-- this comes up because can't assign to ()
+tupledOrUnderscore vs = if length vs > 0 then tupled (map pretty vs) else text "_"
+
+pslice vs = brackets $
+ sepBy "," (map (\x -> case x of (MF v) -> ":" ; (MB v) -> pretty v) vs)
+ <+> "," -- add a list comma to ensure getitem is always passed a tuple.
filterBound = map (\(MF v) -> pretty v) . filter (not.isBound)
-- timv: might want to fuse these into one circuit
--
combinePlans :: [(FRule,[(DFunctAr, Maybe (Cost,Action))])] ->
- M.Map DFunctAr [(FRule, Cost, Action)]
+ M.Map DFunctAr [(FRule, Cost, Action)]
combinePlans = go (M.empty)
where
go m [] = m
go' xs _ [] m = go m xs
go' xs fr ((fa,mca):ys) m =
case mca of
- Nothing -> throw $ TLENoUpdPlan fr fa
+ Nothing -> throw $ TLENoUpdPlan fr fa
Just (c,a) -> go' xs fr ys $ mapInOrApp fa (fr,c,a) m
py (f,a) mu (FRule h _ _ r span _) dope =
<+> colon
Nothing -> "@initializer" <> pfsa
`above` "def _():"
- `above` (indent 4 $ go dope emit)
+ `above` (indent 4 $ "for _ in [None]:")
+ `above` (indent 8 $ go dope emit)
where
pfsa = (parens $ dquotes $
aggm <- case buildAggMap frs of
Left e -> throw $ TLEAggPlan e
Right x -> return x
+
+ forM (M.toList aggm) $ \(k,v) -> do {
+ hPutStrLn fh $ "# " ++ (show k) ++ "->" ++ show v
+ }
+
cPlans <- return $! combinePlans -- crux plans
$ map (\x -> (x, planEachEval headVar valVar x)) frs
forM_ (M.toList cPlans) $ \(fa, ps) -> do -- plans aggregated by functor/arity