haskell - How do you translate from lambda terms to interaction nets? -
on this paper, author suggests translation between lambda terms:
data term = 0 | succ term | app term term | lam term
and interaction nets:
data net = -- if understood correctly apply net net net | abstract net net net | delete net net int | duplicate net net net int | erase net
unfortunately can not understand compilation algorithm. seems actual algorithm missing, , have no idea means images on third page. i've tried understanding looking @ published source code, author defines using own graph rewriting dsl have learn first. how translation implemented normal haskell function?
i have implementation of interaction net reduction in haskell uses stref
s represent net graph structure in mutable way:
data nodetype = nrot | nlam | napp | ndup int | nera deriving (show) type nodeid = int type port s = stref s (node s, portnum) data node s = node { nodetype :: !nodetype , nodeid :: !nodeid , nodeport0, nodeport1, nodeport2 :: !(port s) }
conversion lambda terms implemented in separate module. not nicest code i've ever written, because it's straight transliteration of javascript implementation , didn't take time understand js version doing:
encodelam :: lam -> intnet s (node s) encodelam lam = nexttag <- ref <- lift $ newstref 0 return $ lift $ modifystref ref succ readstref ref let go scope (lam body) = del <- mknode nera lam <- mknode nlam linkhalf lam p0 link (lam, p1) (del, p0) link (del, p1) (del, p2) bod <- go (lam:scope) (lam, p2) body linkhalf lam p2 bod return (lam, p0) go scope (app f e) = app <- mknode napp linkhalf app p2 linkhalf app p0 =<< go scope (app, p0) f linkhalf app p1 =<< go scope (app, p1) e return (app, p2) go scope (var v) = let lam = scope !! v (target, targetport) <- readport lam p1 case nodetype target of nera -> linkhalf lam p1 return (lam, p1) _ -> dup <- mknode . ndup =<< nexttag linkhalf dup p0 (lam, p1) linkhalf dup p1 link (dup, p2) =<< readport lam p1 linkhalf lam p1 (dup, p0) return (dup, p1) root <- asks root enc <- go [] (root, p0) lam linkhalf root p0 enc return root
it implements reverse transformation:
decodelam :: node s -> intnet s lam decodelam root = (setdepth, getdepth) <- ref <- lift $ newstref mempty let set node depth = lift $ modifystref ref $ intmap.insertwith (\ _new old -> old) (nodeid node) depth node = lift $ (! nodeid node) <$> readstref ref return (set, get) let go depth exit (node, port) = setdepth node depth case nodetype node of ndup _ -> let (port', exit') = case port of p0 -> (head exit, tail exit) _ -> (p0, port:exit) go depth exit' =<< readport node port' nlam -> case port of p1 -> depth' <- getdepth node return $ var (depth - depth' - 1) _ -> lam <$> (go (succ depth) exit =<< readport node p2) napp -> f <- go depth exit =<< readport node p0 e <- go depth exit =<< readport node p1 return $ app f e go 0 [] =<< readport root p0
Comments
Post a Comment