{- $Id: Gener.hs,v 1.12.2.3 2009/02/20 18:00:02 orlov Exp $ -} {- vim: set syntax=haskell expandtab tabstop=4: -} module Gener {-( genStates )-} where import Prelude hiding (Num (negate)) import List (maximumBy, nubBy) import XSG hiding (State) import PPT ------------------------------------------------------------------ type GTab = [((Exp, Exp), Var)] type GenData = (GTab, (Exps, Terms, Terms), (Exps, Terms, Terms)) type FuncIO = (Vars, Exps) type State = (Terms, Exps) type XState = (Vars, State) ------------------------------------------------------------------ instance Show XState where showsPrec 0 (vs, st) = shows vs . (" ==> " ++) . shows st instance Show (XState, XState, XState) where showsPrec 0 (xst1, xst2, xst3) = shows xst1 . ("\n" ++) . shows xst2 . ("\n" ++). shows xst3 ------------------------------- GEN ------------------------------ class GEN a where mkT :: a -> a -> Index -> GTab gen :: a -> a -> GTab -> a instance GEN Var where mkT vF@(L _) vG@(L _) idx = [((v2e vF, v2e vG), L idx)] gen vF@(L _) vG@(L _) tab = head [v | (es, v) <- tab, es==(v2e vF, v2e vG)] instance GEN Exp where mkT eF eG idx = mkT' [] eF eG idx where mkT' ps (C cNF esF) (C cNG esG) idx | (fst cNF)==(fst cNG) = if ((snd cNF)==(snd cNG) || (cNF, cNG) `elem` ps || (cNG, cNF) `elem` ps) then [] else concat $ zipWith3 (mkT' ((cNF,cNG):ps)) esF esG (newIdxs idx) mkT' ps eF eG idx = [((eF, eG), X idx)] gen (C cNF esF) (C cNG esG) tab | (fst cNF)==(fst cNG) = C cNF (gen esF esG tab) gen eF eG tab = head [v2e v | (es, v) <- tab, es==(eF,eG)] instance GEN Term where mkT (vsF := (fNF, esF)) (vsG := (fNG, esG)) idx | fNF==fNG = mkT esF esG idx gen (vsF := (fNF, esF)) (vsG := (fNG, esG)) tab | fNF==fNG = ((gen vsF vsG tab) := (fNF, gen esF esG tab)) instance GEN Branch where mkT (tsF, [], esF) (tsG, [], esG) idx = mkT (tsF, esF) (tsG, esG) idx gen (tsF, [], esF) (tsG, [], esG) tab = (gen tsF tsG tab, [], gen esF esG tab) instance GEN a => GEN [a] where mkT xsF xsG idx = concat $ zipWith3 mkT xsF xsG (newIdxs idx) gen xsF xsG tab = zipWith3 gen xsF xsG (repeat tab) instance (GEN a, GEN b) => GEN (a, b) where mkT (xsF, ysF) (xsG, ysG) idx = (mkT xsF xsG idx1)++(mkT ysF ysG idx2) where idx1:idx2:_ = newIdxs idx ---------------------------- GENSTATES --------------------------- instance Eq Term where t1 == t2 = (getTid t1)==(getTid t2) instance Eq Exp where (VAR v1 ) == (VAR v2 ) = v1==v2 (C cN1 _) == (C cN2 _) = cN1==cN2 _ == _ = False simplifyGTab :: GTab -> GTab simplifyGTab = nubBy (\x1 x2 -> (fst x1)==(fst x2)) findPretend :: GTab -> Terms -> Terms -> Maybe (Term, Term) findPretend tab tsF tsG = findNext [(weight (zip vsF vsG), (tF, tG)) | tF@(vsF:=(fNF, _)) <- tsF, tG@(vsG:=(fNG, _)) <- tsG, fNF==fNG] where pairs = [(vF, vG) | ((VAR vF, VAR vG), _) <- tab] weight xs = length (filter (`elem` xs) pairs) comp x1 x2 = compare (fst x1) (fst x2) findNext [] = Nothing findNext xs = Just (snd (maximumBy comp xs)) genLoop :: GenData -> Index -> GenData genLoop gData@(tab, (esF, gtsF, tsF), (esG, gtsG, tsG)) idx = case findPretend tab tsF tsG of Nothing -> gData Just (tF, tG) -> genLoop gData' idx1 where ptsF = (esF, gtsF+.[tF], tsF-.[tF]) ptsG = (esG, gtsG+.[tG], tsG-.[tG]) gData' = (tab++(mkT tF tG idx2), ptsF, ptsG) idx1:idx2:_ = newIdxs idx ioFGH :: GTab -> Terms -> Terms -> (FuncIO, FuncIO, FuncIO) ioFGH tab tsF tsG = ((vLsF, esF), (vLsG, esG), (vXsH, eLsH)) where (esF , esG , vXsH) = unzip3 [(eF, eG, vH) | ((eF, eG), vH@(X _)) <- tab] (vLsF, vLsG, eLsH) = unzip3 [(vF, vG, eH) | ((eF, eG), vH@(L _)) <- tab, let vF = e2v eF vG = e2v eG eH = v2e vH vsF = (getLVars esF)+.(rhsLVars tsF) vsG = (getLVars esG)+.(rhsLVars tsG), vF `elem` vsF || vG `elem` vsG] mkXStateFG :: Vars -> Terms -> FuncIO -> Index -> XState mkXStateFG vXs ts (vLs, es) idx = (vXs++vLs, (ts, es))/.s where s = zipWith (:->) vLs (map (v2e.X) $ newIdxs idx) mkXStateH :: Terms -> Exps -> FuncIO -> XState mkXStateH tsH esH (vXsH, eLsH) =(vXsH, (tsH, esH++eLsH)) lhsVars :: Terms -> Vars lhsVars = getVars . map (\(vs:=_) -> vs) rhsLVars :: Terms -> Vars rhsLVars = getLVars . map (\(_:=(_,es)) -> es) genStates :: Branch -> Branch -> Index -> (XState, XState, XState) genStates stF@(tsF, _, esF0) stG@(tsG, _, esG0) idx = (xstH, xstF, xstG) where (tsF0, tsG0) = unzip [(tF, tG) | tF <- tsF, tG <- tsG, (getTid tF)==(getTid tG)] tab0 = mkT (tsF0, esF0) (tsG0, esG0) idx1 gData0 = (tab0, (esF0, tsF0, tsF-.tsF0), (esG0, tsG0, tsG-.tsG0)) gData1 = genLoop gData0 idx2 (tab1, (esF1, gtsF1, tsF1), (esG1, gtsG1, tsG1)) = gData1 tab2 = mkT (lhsVars gtsF1) (lhsVars gtsG1) idx3 tab3 = simplifyGTab (tab2++tab1) (ioF, ioG, ioH) = ioFGH tab3 tsF1 tsG1 xstF = mkXStateFG (getXVars stF) tsF1 ioF idx4 xstG = mkXStateFG (getXVars stG) tsG1 ioG idx5 xstH = mkXStateH (gen gtsF1 gtsG1 tab3) (gen esF1 esG1 tab3) ioH idx1:idx2:idx3:idx4:idx5:_ = newIdxs idx ------------------------------------------------------------------ state1 = ( [ [L [1]] := ("F", [VAR (L [4])]), [L [2]] := ("G", [VAR (L [3])]), [L [3], L [4]] := ("H", [VAR (X [11])]) ] ,[], [VAR (L [1]), VAR (L [2])] ) state2 = ( [ [L [10]] := ("F", [C ("123",[]) [VAR (L [40])]]), [L [20]] := ("G", [VAR (L [30])]), [L [30], L [40]] := ("H", [VAR (X [110])]) ] ,[], [VAR (L [10]), VAR (L [20])] ) t = genStates state1 state2 [570] {- e1 = C "CONS" [C "C1" [], C "C1" []] e2 = C "CONS" [C "C2" [], C "C2" []] test = gen [e1, e1] [e2, e1] (mkT [e1, e1] [e2, e1] [57]) stateA = [ RES [VAR (L [1]), VAR (L [2])], [L [1]] := (CALL "F" [VAR (X [4])]), [L [2]] := (CALL "F" [VAR (X [3])]) ] stateB = [ RES [VAR (L [10]), VAR (L [20])], [L [10]] := (CALL "F" [VAR (X [30])]), [L [20]] := (CALL "F" [VAR (X [30])]) ] tt = genStates stateA stateB [570] -}