From: timv Date: Wed, 12 Dec 2012 05:40:24 +0000 (-0500) Subject: FIX: syntactic issues - can't assign to "()" X-Git-Url: https://hydra-www.ietfng.org/gitweb/?a=commitdiff_plain;h=bf2a25f69a1fdcbf7a18e7c42b621ef1e0d7751c;p=dyna2 FIX: syntactic issues - can't assign to "()" FIX: "continue" cases in for-loops --- diff --git a/bin/stdlib.py b/bin/stdlib.py index f3aa4b6..adb1943 100644 --- a/bin/stdlib.py +++ b/bin/stdlib.py @@ -25,6 +25,9 @@ Call indirection """ +#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 @@ -136,11 +139,13 @@ class Chart(object): # 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): @@ -190,7 +195,6 @@ def register(fn): register.handlers = defaultdict(list) - def initializer(_): def wrap(handler): @@ -212,13 +216,17 @@ def update_dispatcher((fn, idx), val): 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 @@ -279,13 +287,38 @@ def run_agenda(): 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 @@ -294,45 +327,13 @@ def delete(item, val): _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() diff --git a/examples/papa2.dyna b/examples/papa2.dyna index 7834e3d..8e14d76 100644 --- a/examples/papa2.dyna +++ b/examples/papa2.dyna @@ -4,6 +4,10 @@ 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. @@ -23,13 +27,15 @@ rewrite("Det", "a") += 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). diff --git a/src/Dyna/Backend/Python.hs b/src/Dyna/Backend/Python.hs index 9abe78c..e6a91d9 100644 --- a/src/Dyna/Backend/Python.hs +++ b/src/Dyna/Backend/Python.hs @@ -76,11 +76,17 @@ instance Exception TopLevelException 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)) @@ -91,13 +97,17 @@ pdope (OPCall v vs f) = pretty v <+> equals 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) @@ -117,7 +127,7 @@ pf f vs = pretty f <> (tupled $ map pretty vs) -- 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 @@ -126,7 +136,7 @@ combinePlans = go (M.empty) 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 = @@ -139,7 +149,8 @@ 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 $ @@ -194,6 +205,11 @@ processFile_ fileName fh = do 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