From: Adam Megacz Date: Sun, 13 Apr 2014 19:10:15 +0000 (-0700) Subject: improvements to examples/ X-Git-Url: http://git.megacz.com/?p=coq-hetmet.git;a=commitdiff_plain;h=c700f5a65d664d4c0a3e76d33aa3769266bf330c;ds=sidebyside improvements to examples/ --- diff --git a/examples/BitSerialHardware.hs b/examples/BitSerialHardware.hs index 2e82b0d..0a35247 100644 --- a/examples/BitSerialHardware.hs +++ b/examples/BitSerialHardware.hs @@ -1,10 +1,13 @@ -{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts #-} +{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-} module BitSerialHardware(Wire,BitSerialHardwarePrimitives(..)) where import Control.GArrow import Control.Category import GArrowPretty import Prelude hiding (id, (.)) import Text.PrettyPrint.HughesPJ +import GArrowPortShape +import GArrowSkeleton +import GArrowTikZ ------------------------------------------------------------------------------ -- Bit-Serial Hardware Primitives @@ -45,3 +48,23 @@ instance BitSerialHardwarePrimitives SourceCode where probe id = SC False $ text "probe" <+> (text . show) id oracle id = SC False $ text "oracle" <+> (text . show) id +instance BitSerialHardwarePrimitives (GArrowSkeleton Opaque) where + reg = GAS_misc reg' + where reg' = MkOpaque "reg" $ + do x <- freshM + return $ GASPortPassthrough (PortFree x) (PortFree x) reg' + xor = GAS_misc xor' + where xor' = MkOpaque "xor" $ + do x <- freshM + return $ GASPortPassthrough (PortTensor (PortFree x) (PortFree x)) (PortFree x) xor' + high = undefined + low = undefined + not = undefined + or = undefined + and = undefined + mux2 = undefined + maj3 = undefined + loop vals = undefined + fifo len = undefined + probe id = undefined + oracle id = undefined diff --git a/examples/BitSerialHardware.hs- b/examples/BitSerialHardware.hs- new file mode 100644 index 0000000..0a35247 --- /dev/null +++ b/examples/BitSerialHardware.hs- @@ -0,0 +1,70 @@ +{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-} +module BitSerialHardware(Wire,BitSerialHardwarePrimitives(..)) where +import Control.GArrow +import Control.Category +import GArrowPretty +import Prelude hiding (id, (.)) +import Text.PrettyPrint.HughesPJ +import GArrowPortShape +import GArrowSkeleton +import GArrowTikZ + +------------------------------------------------------------------------------ +-- Bit-Serial Hardware Primitives + +data Wire = Wire + +class (GArrowSwap v (,) (), GArrowDrop v (,) (), GArrowCopy v (,) (), GArrowLoop v (,) ()) => + BitSerialHardwarePrimitives v where + high :: v () Wire + low :: v () Wire + + not :: v Wire Wire + xor :: v (Wire,Wire) Wire + or :: v (Wire,Wire) Wire + and :: v (Wire,Wire) Wire + mux2 :: v (Wire,(Wire,Wire)) Wire + maj3 :: v (Wire,(Wire,Wire)) Wire + reg :: v Wire Wire + + loop :: [Bool] -> v () Wire + fifo :: Int -> v Wire Wire + + probe :: Int -> v Wire Wire + oracle :: Int -> v () Wire + +instance BitSerialHardwarePrimitives SourceCode where + high = SC False $ text "high" + low = SC False $ text "low" + not = SC False $ text "not" + xor = SC False $ text "xor" + or = SC False $ text "or" + and = SC False $ text "and" + mux2 = SC False $ text "mux2" + maj3 = SC False $ text "maj3" + reg = SC False $ text "reg" + loop vals = SC False $ text "loop" <+> (brackets $ hcat $ punctuate comma $ map (text . show) vals) + fifo len = SC False $ text "fifo" <+> (text . show) len + probe id = SC False $ text "probe" <+> (text . show) id + oracle id = SC False $ text "oracle" <+> (text . show) id + +instance BitSerialHardwarePrimitives (GArrowSkeleton Opaque) where + reg = GAS_misc reg' + where reg' = MkOpaque "reg" $ + do x <- freshM + return $ GASPortPassthrough (PortFree x) (PortFree x) reg' + xor = GAS_misc xor' + where xor' = MkOpaque "xor" $ + do x <- freshM + return $ GASPortPassthrough (PortTensor (PortFree x) (PortFree x)) (PortFree x) xor' + high = undefined + low = undefined + not = undefined + or = undefined + and = undefined + mux2 = undefined + maj3 = undefined + loop vals = undefined + fifo len = undefined + probe id = undefined + oracle id = undefined diff --git a/examples/Demo.hs b/examples/Demo.hs index 579bf4d..fb8666f 100644 --- a/examples/Demo.hs +++ b/examples/Demo.hs @@ -1,21 +1,33 @@ {-# OPTIONS_GHC -XModalTypes -fflatten -funsafe-skolemize -dcore-lint -XScopedTypeVariables -fsimpleopt-before-flatten #-} -module Demo (demo) where +module Demo ({-sample1,sample2,-}sample5,sample6) where - -demo const mult = +sample5 :: forall c . (Int -> <{Int}>@c) -> <{Int -> Int -> Int}>@c -> <{Int -> Int}>@c +sample5 const <[ (*) ]> = <{ \y -> - let foo = ~~mult (~~mult foo (~~mult y foo)) (~~mult y ~~(const 3)) + let foo = (~~(const 3) * foo) * y in foo }> +sample6 :: forall c . (Int -> <{Int}>@c) -> <{Int -> Int -> Int}>@c -> <{Int -> Int}>@c +sample6 const <{ (*) }> = pow 6 + where + --pow :: Int -> <{ Int -> Int }>@a + pow 0 = <{ \x -> ~~(const 1) }> + pow 1 = <{ \x -> x }> + pow n = <{ \x -> x * ~~(pow (n - 1)) x }> -{- -demo const mult = +demo2 :: + forall c . + (Int -> <{Int}>@c) -> + <{Int -> Int -> Int}>@c -> + <{Int -> Int}>@c + +demo2 const mult = <{ \y -> ~~mult (~~(const 1)) (~~mult y y) }> --} + @@ -144,11 +156,6 @@ demo const mult = in four }> -} -demo :: - forall c . - (Int -> <{Int}>@c) -> - <{Int -> Int -> Int}>@c -> - <{Int -> Int}>@c {- demo const mult = diff --git a/examples/DemoMain.hs b/examples/DemoMain.hs index c511bfa..0da3644 100644 --- a/examples/DemoMain.hs +++ b/examples/DemoMain.hs @@ -1,7 +1,62 @@ +{-# LANGUAGE RankNTypes, FlexibleContexts, NoMonomorphismRestriction, ScopedTypeVariables #-} +import System.IO import Control.Category import GArrowTikZ import GHC.HetMet.Private -import Control.GArrow -import Demo +import GArrowSkeleton +import GArrowPortShape +import GArrowAssTypes +import BitSerialHardware +import qualified Demo -main = tikz demo +tikzExample1 = + ga_copy >>> + ga_swap >>> + ga_first ga_drop >>> + ga_cancell + +tikzExample2 = + ga_uncancelr >>> + ga_first ga_copy >>> + ga_swap >>> + ga_second (ga_first ga_drop >>> + ga_cancell) >>> + ga_cancell + +oscillator = + ga_loopl (ga_first reg >>> + xor >>> + ga_copy) + +oconst :: Int -> Opaque () a +oconst c = MkOpaque ("{\\large{"++(show c)++"}}") $ + do x <- freshM + return $ GASPortPassthrough PortUnit (PortFree x) (oconst c) + +omult :: Opaque (a,a) a +omult = MkOpaque "{\\large{*}}" $ + do x <- freshM + return $ GASPortPassthrough (PortTensor (PortFree x) (PortFree x)) (PortFree x) omult + +main = do let const c = PGArrowD $ GAS_misc $ oconst c + let mult = PGArrowD $ GAS_misc omult + + sample5 <- toTikZ $ beautify $ optimize $ unG (Demo.sample5 const mult) + putStrLn $ tikz_header ++ sample5 ++ tikz_footer + withFile ".build/sample5.tex" WriteMode (\file -> hPutStr file sample5) + + sample1 <- toTikZ $ skelify' tikzExample1 + --putStrLn $ tikz_header ++ sample1 ++ tikz_footer + withFile ".build/sample1.tex" WriteMode (\file -> hPutStr file sample1) + + sample2 <- toTikZ $ skelify' tikzExample2 + --putStrLn $ tikz_header ++ sample2 ++ tikz_footer + withFile ".build/sample2.tex" WriteMode (\file -> hPutStr file sample2) + + sample3 <- toTikZ $ skelify'' oscillator + --putStrLn $ tikz_header ++ sample3 ++ tikz_footer + withFile ".build/sample3.tex" WriteMode (\file -> hPutStr file sample3) + + sample6 <- toTikZ $ beautify $ optimize $ unG (Demo.sample6 const mult) + --putStrLn $ tikz_header ++ sample6 ++ tikz_footer + withFile ".build/sample6.tex" WriteMode (\file -> hPutStr file sample6) diff --git a/examples/GArrowAssTypes.hs b/examples/GArrowAssTypes.hs new file mode 100644 index 0000000..45d6204 --- /dev/null +++ b/examples/GArrowAssTypes.hs @@ -0,0 +1,57 @@ +{-# LANGUAGE RankNTypes, FlexibleContexts, NoMonomorphismRestriction, ScopedTypeVariables #-} +-- +-- | +-- Module : GArrowAssTypes +-- Copyright : none +-- License : public domain +-- +-- Maintainer : Adam Megacz +-- Stability : experimental +-- +-- | This module is a gigantic type inference hack; it redefines all of the +-- ga_functions with a slightly more specific type whereby each type g +-- which is a GArrow instance also has an *associated type* (GArrowTensor g) +-- for its tensor and (GArrowUnit g) for its unit. +-- +-- DO import this module without qualification if you plan on +-- writing GArrow-expressions with as few annotations as possible. +-- +-- DO NOT import this module without qualification if you plan on +-- creating new instances of GArrow. Use "import qualified" or +-- don't import it at all. +-- + +module GArrowAssTypes + (ga_copy + ,ga_drop + ,ga_swap + , module Control.GArrow + ) + where +import System.IO +import qualified Control.GArrow as G +import Control.GArrow hiding (ga_copy, ga_drop, ga_swap) + +{- +ga_copy :: forall x . forall g . GArrowCopy g (GArrowTensor g) (GArrowUnit g) => g x (GArrowTensor g x x) +ga_copy = G.ga_copy + +ga_drop :: forall x . forall g . GArrowDrop g (GArrowTensor g) (GArrowUnit g) => g x (GArrowUnit g) +ga_drop = G.ga_drop + +ga_swap :: forall x y . forall g . GArrowSwap g (GArrowTensor g) (GArrowUnit g) => g (GArrowTensor g x y) (GArrowTensor g y x) +ga_swap = G.ga_swap +-} + + +ga_copy :: forall x . forall g . GArrowCopy g (,) () => g x ((,) x x) +ga_copy = G.ga_copy + +ga_drop :: forall x . forall g . GArrowDrop g (,) () => g x () +ga_drop = G.ga_drop + +ga_swap :: forall x y . forall g . GArrowSwap g (,) () => g ((,) x y) ((,) y x) +ga_swap = G.ga_swap + + + diff --git a/examples/GArrowSkeleton.hs b/examples/GArrowSkeleton.hs index b320336..a71486f 100644 --- a/examples/GArrowSkeleton.hs +++ b/examples/GArrowSkeleton.hs @@ -23,7 +23,7 @@ -- -- A normal form theorem and normalization algorithm are being prepared. -- -module GArrowSkeleton (GArrowSkeleton(..), mkSkeleton, OptimizeFlag(..), optimize, beautify) +module GArrowSkeleton (GArrowSkeleton(..), mkSkeleton, OptimizeFlag(..), optimize, beautify, skelify) where import Prelude hiding ( id, (.), lookup, repeat ) import Control.Category @@ -87,6 +87,9 @@ instance GArrowCopyDropSwapLoop (GArrowSkeleton m) instance GArrowInclusion (GArrowSkeleton m) (,) () m where ga_inc = GAS_misc +skelify :: (forall g . (GArrowCopyDropSwapLoop g, GArrowInclusion g (,) () m) => g x y) -> GArrowSkeleton m x y +skelify = \g -> g + -- -- | Simple structural equality on skeletons. NOTE: two skeletons -- with the same shape but different types will nonetheless be "equal"; @@ -344,6 +347,8 @@ gasx2gas (GASX_loopr gl) = GAS_loopr $ gasl2gas gl optimizel :: GArrowSkeletonL m x y -> GArrowSkeletonL m x y +--optimizel (GASL_comp (GASL_Y (GASY_X GAS_uncancelr)) (GASL_Y (GASY_X GASX_copy))) = +-- (GASL_comp (GASL_Y (GASY_X GAS_uncancelr)) (GASL_Y (GASY_X GASX_copy))) optimizel (GASL_id ) = GASL_id optimizel (GASL_Y gy ) = GASL_Y $ optimizey gy optimizel (GASL_comp gy (GASL_comp gy' gl)) | Just x <- optpair gy gy' = optimizel $ gaslcat x gl diff --git a/examples/GArrowTikZ.hs b/examples/GArrowTikZ.hs index dcf7c8f..1b15fab 100644 --- a/examples/GArrowTikZ.hs +++ b/examples/GArrowTikZ.hs @@ -12,7 +12,7 @@ -- You must have lp_solve installed in order for this to work. -- -module GArrowTikZ (tikz) +module GArrowTikZ (tikz,Opaque(..),toTikZ,tikz_header,tikz_footer,skelify',skelify'') where import System.Process import Prelude hiding ( id, (.), lookup ) @@ -27,6 +27,13 @@ import GArrowSkeleton import GArrowPortShape import GHC.HetMet.Private +skelify' :: (forall g . (GArrowCopy g (,) (), GArrowDrop g (,) (), GArrowSwap g (,) (), GArrowLoop g (,) ()) => g x y) -> + GArrowSkeleton Opaque x y +skelify' = \g -> g + +skelify'' :: GArrowSkeleton Opaque x y -> GArrowSkeleton Opaque x y +skelify'' = \g -> g + ------------------------------------------------------------------------------ -- Tracks @@ -87,7 +94,7 @@ instance ToDiagram Opaque where do { (top, x ,bot) <- alloc inp ; (_, y ,_) <- alloc outp --; constrainEq x y - ; simpleDiag s top x y bot [] } + ; simpleDiag'' s top x y bot [] "black" } toDiagram q = mkdiag q -- do (top, x ,bot) <- alloc inp @@ -210,22 +217,22 @@ mkdiag (GASPortShapeWrapper inp outp x) = mkdiag' x ; let r tp x1 y1 x2 y2 = drawBox x1 y1 x2 y2 "gray!50" "cancell" ++ drawWires tp x1 y x2 y "black" ++ drawLine x1 (tp!lowermost x) ((x1+x2)/2) (tp!uppermost y) "gray!50" "dashed" - ; return $ DiagramBox 2 top (TT x y) r y bot } + ; return $ DiagramBox 2.4 top (TT x y) r y bot } mkdiag' GAS_cancelr = do { (top,(TT x y),bot) <- alloc inp ; let r tp x1 y1 x2 y2 = drawBox x1 y1 x2 y2 "gray!50" "cancelr" ++ drawWires tp x1 x x2 x "black" ++ drawLine x1 (tp!uppermost y) ((x1+x2)/2) (tp!lowermost x) "gray!50" "dashed" - ; return $ DiagramBox 2 top (TT x y) r x bot } + ; return $ DiagramBox 2.4 top (TT x y) r x bot } mkdiag' GAS_uncancell = do { (top,(TT x y),bot) <- alloc outp ; let r tp x1 y1 x2 y2 = drawBox x1 y1 x2 y2 "gray!50" "uncancell" ++ drawWires tp x1 y x2 y "black" ++ drawLine ((x1+x2)/2) (tp!uppermost y) x2 (tp!lowermost x) "gray!50" "dashed" - ; return $ DiagramBox 2 top y r (TT x y) bot } + ; return $ DiagramBox 2.8 top y r (TT x y) bot } mkdiag' GAS_uncancelr = do { (top,(TT x y),bot) <- alloc outp ; let r tp x1 y1 x2 y2 = drawBox x1 y1 x2 y2 "gray!50" "uncancelr" ++ drawWires tp x1 x x2 x "black" ++ drawLine ((x1+x2)/2) (tp!lowermost x) x2 (tp!uppermost y) "gray!50" "dashed" - ; return $ DiagramBox 2 top x r (TT x y) bot } + ; return $ DiagramBox 2.8 top x r (TT x y) bot } mkdiag' GAS_drop = do { (top, x ,bot) <- alloc inp ; (_, y ,_) <- alloc outp ; constrainEq x y @@ -237,7 +244,7 @@ mkdiag (GASPortShapeWrapper inp outp x) = mkdiag' x drawWires tp x1 x ((x1+x2)/2) x "black" ++ drawWires tp ((x1+x2)/2) x x2 y "black" ++ drawWires tp ((x1+x2)/2) x x2 z "black" - ; return $ DiagramBox 2 top x r (TT y z) bot + ; return $ DiagramBox defaultWidth top x r (TT y z) bot } mkdiag' GAS_swap = do { (top,(TT x y),bot) <- alloc inp ; (top,(TT x' y'),bot) <- alloc outp @@ -265,7 +272,7 @@ mkdiag (GASPortShapeWrapper inp outp x) = mkdiag' x drawWires tp x1 z x2 z "black" ; let pin = (TT (TT x y) z) ; let pout = (TT x (TT y z)) - ; return $ if draw_assoc then DiagramBox 2 top pin r pout bot else DiagramBox 0 top pin noRender pout bot + ; return $ if draw_assoc then DiagramBox defaultWidth top pin r pout bot else DiagramBox 0 top pin noRender pout bot } mkdiag' GAS_unassoc = do { (top,(TT x (TT y z)),bot) <- alloc inp @@ -288,7 +295,7 @@ mkdiag (GASPortShapeWrapper inp outp x) = mkdiag' x drawWires tp x1 z x2 z "black" ; let pin = (TT x (TT y z)) ; let pout = (TT (TT x y) z) - ; return $ if draw_assoc then DiagramBox 2 top pin r pout bot else DiagramBox 0 top pin noRender pout bot + ; return $ if draw_assoc then DiagramBox defaultWidth top pin r pout bot else DiagramBox 0 top pin noRender pout bot } mkdiag' (GAS_loopl f) = do { f' <- mkdiag' f ; l <- allocLoop (case (getIn f') of (TT z _) -> z ; _ -> error "GAS_loopl: mismatch") @@ -300,13 +307,15 @@ mkdiag (GASPortShapeWrapper inp outp x) = mkdiag' x ; return $ DiagramLoopBot f' l } mkdiag' (GAS_misc f ) = mkdiag f +defaultWidth = 2 + diagramBox :: TrackIdentifier -> Tracks -> BoxRenderer -> Tracks -> TrackIdentifier -> ConstraintM Diagram diagramBox ptop pin r pout pbot = do { constrain ptop LT (uppermost pin) (-1) ; constrain pbot GT (lowermost pin) 1 ; constrain ptop LT (uppermost pout) (-1) ; constrain pbot GT (lowermost pout) 1 ; constrain ptop LT pbot (-1) - ; return $ DiagramBox 2 ptop pin r pout pbot + ; return $ DiagramBox defaultWidth ptop pin r pout pbot } simpleDiag text ptop pin pout pbot conn = simpleDiag' text ptop pin pout pbot conn "black" simpleDiag' text ptop pin pout pbot conn color = diagramBox ptop pin defren pout pbot @@ -315,6 +324,12 @@ simpleDiag' text ptop pin pout pbot conn color = diagramBox ptop pin defren pout concat (map (\(x,y) -> drawWires tp x1 x x2 y "black") conn) -- ++ wires (x-1) p1 x "green" -- ++ wires (x+w) p2 (x+w+1) "red" +simpleDiag'' text ptop pin pout pbot conn color = diagramBox ptop pin defren pout pbot + where + defren tp x1 y1 x2 y2 = drawBoxC x1 y1 x2 y2 color text ++ + concat (map (\(x,y) -> drawWires tp x1 x x2 y "black") conn) + -- ++ wires (x-1) p1 x "green" + -- ++ wires (x+w) p2 (x+w+1) "red" draw_assoc = False draw_first_second = False @@ -476,7 +491,7 @@ allocLoop (TT t1 t2) = do { x1 <- allocLoop t2 do_lp_solve :: [Constraint] -> IO String do_lp_solve c = do { let stdin = "min: x1;\n" ++ (foldl (++) "" (map show c)) ++ "\n" - ; putStrLn stdin +-- ; putStrLn stdin ; stdout <- readProcess "lp_solve" [] stdin ; return stdout } @@ -503,6 +518,7 @@ lp_solve_to_trackpos s = toTrackPos $ map parse $ catMaybes $ map grab $ lines s toTrackPos [] tr = 0 -- error $ "could not find track "++show tr toTrackPos ((i,f):rest) tr = if (i==tr) then f else toTrackPos rest tr + toTikZ :: (ToDiagram m, Detect m) => GArrowSkeleton m a b -> IO String toTikZ g = let cm = do { let g' = detectShape g @@ -517,46 +533,28 @@ toTikZ g = ; return (t ++ drawWires m 0 (getIn d) 1 (getIn d) "black" ++ drawWires m (width m d+1) (getOut d) (width m d+2) (getOut d) "black") } - - -tikz :: forall c . - (forall g . - (Int -> PGArrow g (GArrowUnit g) Int) -> - (PGArrow g (GArrowTensor g c c) c) -> - PGArrow g c c) - -> IO () -tikz x = tikz' $ beautify $ optimize $ unG (x (\c -> PGArrowD { unG = GAS_misc (oconst c) }) - (PGArrowD { unG = GAS_misc omult })) - -oconst :: Int -> Opaque () a -oconst c = MkOpaque ("const "++(show c)) $ - do x <- freshM - return $ GASPortPassthrough PortUnit (PortFree x) (oconst c) - -omult :: Opaque (a,a) a -omult = MkOpaque "mult" $ - do x <- freshM - return $ GASPortPassthrough (PortTensor (PortFree x) (PortFree x)) (PortFree x) omult - -tikz' example - = do putStrLn "\\documentclass{article}" - putStrLn "\\usepackage[paperwidth=\\maxdimen,paperheight=\\maxdimen]{geometry}" - putStrLn "\\usepackage{tikz}" - putStrLn "\\usepackage{amsmath}" - putStrLn "\\usepackage[tightpage,active]{preview}" - putStrLn "\\begin{document}" - putStrLn "\\setlength\\PreviewBorder{5pt}" - putStrLn "\\begin{preview}" - putStrLn $ "\\begin{tikzpicture}[every on chain/.style={join=by ->},yscale=-1]" - tikz <- toTikZ example - putStrLn tikz - putStrLn "\\end{tikzpicture}" - putStrLn "\\end{preview}" - --putStrLn "\\pagebreak" - --putStrLn "\\begin{align*}" - --putStr (toTikZ' example) - --putStrLn "\\end{align*}" - putStrLn "\\end{document}" + +tikz_header = + "\\documentclass{article}\n" ++ + "\\usepackage[paperwidth=\\maxdimen,paperheight=\\maxdimen]{geometry}\n" ++ + "\\usepackage{tikz}\n" ++ + "\\usepackage{amsmath}\n" ++ + "\\usepackage[tightpage,active]{preview}\n" ++ + "\\begin{document}\n" ++ + "\\setlength\\PreviewBorder{5pt}\n" ++ + "\\begin{preview}\n" ++ + "\\begin{tikzpicture}[every on chain/.style={join=by ->},yscale=-1]\n" + +tikz_footer = + "\\end{tikzpicture}\n" ++ + "\\end{preview}\n" ++ + "\\end{document}\n" + +tikz example = + do putStrLn tikz_header + tikz <- toTikZ example + putStrLn tikz + putStrLn tikz_footer -- Random TikZ routines textc x y text color = @@ -571,6 +569,14 @@ drawBox x1 y1 x2 y2 color text = " ("++show (x1*xscale)++","++show (y1*yscale)++") rectangle ("++ show (x2*xscale)++","++show (y2*yscale)++");\n" +drawBoxC x1 y1 x2 y2 color text = + "\\node[anchor=center] at ("++show ((x1+x2)*xscale/2)++"cm,"++show ((y1+y2)*yscale/2)++"cm) "++ + "{{\\tt{"++text++"}}};\n" + ++ + "\\path[draw,color="++color++"]"++ + " ("++show (x1*xscale)++","++show (y1*yscale)++") rectangle ("++ + show (x2*xscale)++","++show (y2*yscale)++");\n" + drawLine x1 y1 x2 y2 color style = "\\path[draw,color="++color++","++style++"] "++ "("++show (x1*xscale)++","++show (y1*yscale)++") -- " ++