{-# LANGUAGE FlexibleContexts #-}
module GraphRewriting.GL.Global where
import Prelude.Unicode
import Graphics.UI.GLUT (addTimerCallback, Window, postRedisplay)
import GraphRewriting.Graph
import GraphRewriting.Graph.Read
import GraphRewriting.Rule
import GraphRewriting.Pattern
import Data.IORef
import GraphRewriting.Layout.RotPortSpec
import qualified Data.Set as Set
import Data.Set (Set)
import Data.List ((\\))
import Control.Monad (when, unless, replicateM_)
import Data.Foldable
import Data.Functor
import Data.Traversable
import Prelude hiding (concat, concatMap, or, elem, foldr, any, mapM)
data GlobalVars n = GlobalVars
{forall n. GlobalVars n -> Graph n
graph ∷ Graph n,
forall n. GlobalVars n -> Bool
paused ∷ Bool,
forall n. GlobalVars n -> Int
selectedRule ∷ Int,
forall n. GlobalVars n -> Set Node
highlighted ∷ Set Node,
forall n. GlobalVars n -> Node -> Rewrite n ()
layoutStep ∷ Node → Rewrite n (),
forall n. GlobalVars n -> Window
canvas ∷ Window,
∷ Window,
forall n. GlobalVars n -> RuleTree n
getRules ∷ RuleTree n}
data LabelledTree a = Branch String [LabelledTree a] | Leaf String a
data LTZipper a = Root | Child String [LabelledTree a] (LTZipper a) [LabelledTree a]
type LTLoc a = (LabelledTree a, LTZipper a)
next ∷ LTLoc a → Maybe (LTLoc a)
next :: forall a. LTLoc a -> Maybe (LTLoc a)
next (Branch String
b (LabelledTree a
t:[LabelledTree a]
ts), LTZipper a
p) = (LabelledTree a, LTZipper a) -> Maybe (LabelledTree a, LTZipper a)
forall a. a -> Maybe a
Just (LabelledTree a
t, String
-> [LabelledTree a] -> LTZipper a -> [LabelledTree a] -> LTZipper a
forall a.
String
-> [LabelledTree a] -> LTZipper a -> [LabelledTree a] -> LTZipper a
Child String
b [] LTZipper a
p [LabelledTree a]
ts)
next (Leaf String
l a
x, LTZipper a
p) = (LabelledTree a, LTZipper a) -> Maybe (LabelledTree a, LTZipper a)
forall a. LTLoc a -> Maybe (LTLoc a)
right (String -> a -> LabelledTree a
forall a. String -> a -> LabelledTree a
Leaf String
l a
x, LTZipper a
p)
next (LabelledTree a, LTZipper a)
_ = Maybe (LabelledTree a, LTZipper a)
forall a. Maybe a
Nothing
nth ∷ Int → LTLoc a → Maybe (LTLoc a)
nth :: forall a. Int -> LTLoc a -> Maybe (LTLoc a)
nth Int
n LTLoc a
l = (Maybe (LTLoc a) -> Maybe (LTLoc a))
-> Maybe (LTLoc a) -> [Maybe (LTLoc a)]
forall a. (a -> a) -> a -> [a]
iterate (Maybe (LTLoc a) -> (LTLoc a -> Maybe (LTLoc a)) -> Maybe (LTLoc a)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= LTLoc a -> Maybe (LTLoc a)
forall a. LTLoc a -> Maybe (LTLoc a)
next) (LTLoc a -> Maybe (LTLoc a)
forall a. a -> Maybe a
Just LTLoc a
l) [Maybe (LTLoc a)] -> Int -> Maybe (LTLoc a)
forall a. HasCallStack => [a] -> Int -> a
!! Int
n
right ∷ LTLoc a → Maybe (LTLoc a)
right :: forall a. LTLoc a -> Maybe (LTLoc a)
right (LabelledTree a
t, Child String
c [LabelledTree a]
ls LTZipper a
p (LabelledTree a
r:[LabelledTree a]
rs)) = (LabelledTree a, LTZipper a) -> Maybe (LabelledTree a, LTZipper a)
forall a. a -> Maybe a
Just (LabelledTree a
r, String
-> [LabelledTree a] -> LTZipper a -> [LabelledTree a] -> LTZipper a
forall a.
String
-> [LabelledTree a] -> LTZipper a -> [LabelledTree a] -> LTZipper a
Child String
c ([LabelledTree a]
ls [LabelledTree a] -> [LabelledTree a] -> [LabelledTree a]
forall α. [α] -> [α] -> [α]
⧺ [LabelledTree a
t]) LTZipper a
p [LabelledTree a]
rs)
right (LabelledTree a
t, Child String
c [LabelledTree a]
ls LTZipper a
p []) = (LabelledTree a, LTZipper a) -> Maybe (LabelledTree a, LTZipper a)
forall a. LTLoc a -> Maybe (LTLoc a)
up (LabelledTree a
t, String
-> [LabelledTree a] -> LTZipper a -> [LabelledTree a] -> LTZipper a
forall a.
String
-> [LabelledTree a] -> LTZipper a -> [LabelledTree a] -> LTZipper a
Child String
c [LabelledTree a]
ls LTZipper a
p []) Maybe (LabelledTree a, LTZipper a)
-> ((LabelledTree a, LTZipper a)
-> Maybe (LabelledTree a, LTZipper a))
-> Maybe (LabelledTree a, LTZipper a)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (LabelledTree a, LTZipper a) -> Maybe (LabelledTree a, LTZipper a)
forall a. LTLoc a -> Maybe (LTLoc a)
right
right (LabelledTree a, LTZipper a)
_ = Maybe (LabelledTree a, LTZipper a)
forall a. Maybe a
Nothing
up ∷ LTLoc a → Maybe (LTLoc a)
up :: forall a. LTLoc a -> Maybe (LTLoc a)
up (LabelledTree a
t, Child String
c [LabelledTree a]
ls LTZipper a
p [LabelledTree a]
rs) = (LabelledTree a, LTZipper a) -> Maybe (LabelledTree a, LTZipper a)
forall a. a -> Maybe a
Just (String -> [LabelledTree a] -> LabelledTree a
forall a. String -> [LabelledTree a] -> LabelledTree a
Branch String
c ([LabelledTree a]
ls [LabelledTree a] -> [LabelledTree a] -> [LabelledTree a]
forall α. [α] -> [α] -> [α]
⧺ [LabelledTree a
t] [LabelledTree a] -> [LabelledTree a] -> [LabelledTree a]
forall α. [α] -> [α] -> [α]
⧺ [LabelledTree a]
rs), LTZipper a
p)
up (LabelledTree a, LTZipper a)
_ = Maybe (LabelledTree a, LTZipper a)
forall a. Maybe a
Nothing
put ∷ LTLoc a → LabelledTree a → LTLoc a
put :: forall a. LTLoc a -> LabelledTree a -> LTLoc a
put (LabelledTree a
_, LTZipper a
p) LabelledTree a
t = (LabelledTree a
t, LTZipper a
p)
top ∷ LTLoc a → LTLoc a
top :: forall a. LTLoc a -> LTLoc a
top (LabelledTree a
t, LTZipper a
Root) = (LabelledTree a
t, LTZipper a
forall a. LTZipper a
Root)
top (LabelledTree a
t, Child String
c [LabelledTree a]
ls LTZipper a
p [LabelledTree a]
rs) = (LabelledTree a, LTZipper a) -> (LabelledTree a, LTZipper a)
forall a. LTLoc a -> LTLoc a
top (String -> [LabelledTree a] -> LabelledTree a
forall a. String -> [LabelledTree a] -> LabelledTree a
Branch String
c ([LabelledTree a]
ls [LabelledTree a] -> [LabelledTree a] -> [LabelledTree a]
forall α. [α] -> [α] -> [α]
⧺ [LabelledTree a
t] [LabelledTree a] -> [LabelledTree a] -> [LabelledTree a]
forall α. [α] -> [α] -> [α]
⧺ [LabelledTree a]
rs), LTZipper a
p)
root ∷ LabelledTree a → LTLoc a
root :: forall a. LabelledTree a -> LTLoc a
root LabelledTree a
t = (LabelledTree a
t, LTZipper a
forall a. LTZipper a
Root)
instance Foldable LabelledTree where
foldr :: forall a b. (a -> b -> b) -> b -> LabelledTree a -> b
foldr a -> b -> b
f b
y (Leaf String
l a
x) = a -> b -> b
f a
x b
y
foldr a -> b -> b
f b
y (Branch String
l [LabelledTree a]
ts) = (LabelledTree a -> b -> b) -> b -> [LabelledTree a] -> b
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((b -> LabelledTree a -> b) -> LabelledTree a -> b -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((b -> LabelledTree a -> b) -> LabelledTree a -> b -> b)
-> (b -> LabelledTree a -> b) -> LabelledTree a -> b -> b
forall a b. (a -> b) -> a -> b
$ (a -> b -> b) -> b -> LabelledTree a -> b
forall a b. (a -> b -> b) -> b -> LabelledTree a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> b -> b
f) b
y [LabelledTree a]
ts
instance Functor LabelledTree where
fmap :: forall a b. (a -> b) -> LabelledTree a -> LabelledTree b
fmap a -> b
f (Leaf String
l a
x) = String -> b -> LabelledTree b
forall a. String -> a -> LabelledTree a
Leaf String
l (a -> b
f a
x)
fmap a -> b
f (Branch String
l [LabelledTree a]
ts) = String -> [LabelledTree b] -> LabelledTree b
forall a. String -> [LabelledTree a] -> LabelledTree a
Branch String
l ([LabelledTree b] -> LabelledTree b)
-> [LabelledTree b] -> LabelledTree b
forall a b. (a -> b) -> a -> b
$ (a -> b) -> LabelledTree a -> LabelledTree b
forall a b. (a -> b) -> LabelledTree a -> LabelledTree b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (LabelledTree a -> LabelledTree b)
-> [LabelledTree a] -> [LabelledTree b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [LabelledTree a]
ts
instance Traversable LabelledTree where
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LabelledTree a -> f (LabelledTree b)
traverse a -> f b
f (Leaf String
l a
x) = String -> b -> LabelledTree b
forall a. String -> a -> LabelledTree a
Leaf String
l (b -> LabelledTree b) -> f b -> f (LabelledTree b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
x
traverse a -> f b
f (Branch String
l [LabelledTree a]
ts) = String -> [LabelledTree b] -> LabelledTree b
forall a. String -> [LabelledTree a] -> LabelledTree a
Branch String
l ([LabelledTree b] -> LabelledTree b)
-> f [LabelledTree b] -> f (LabelledTree b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LabelledTree a -> f (LabelledTree b))
-> [LabelledTree a] -> f [LabelledTree b]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((a -> f b) -> LabelledTree a -> f (LabelledTree b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LabelledTree a -> f (LabelledTree b)
traverse a -> f b
f) [LabelledTree a]
ts
showRuleTree ∷ RuleTree n → String
showRuleTree :: forall n. RuleTree n -> String
showRuleTree = Int -> Int -> (Int -> Int -> Int) -> LabelledTree Int -> String
forall a.
Show a =>
Int -> a -> (a -> a -> a) -> LabelledTree a -> String
showLabelledTree Int
2 Int
0 Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) (LabelledTree Int -> String)
-> (RuleTree n -> LabelledTree Int) -> RuleTree n -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Rule n) -> Int) -> RuleTree n -> LabelledTree Int
forall a b. (a -> b) -> LabelledTree a -> LabelledTree b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, Rule n) -> Int
forall a b. (a, b) -> a
fst
showLabelledTree ∷ Show a ⇒ Int → a → (a → a → a) → LabelledTree a → String
showLabelledTree :: forall a.
Show a =>
Int -> a -> (a -> a -> a) -> LabelledTree a -> String
showLabelledTree Int
indentation a
init a -> a -> a
combine = (a, String) -> String
forall a b. (a, b) -> b
snd ((a, String) -> String)
-> (LabelledTree a -> (a, String)) -> LabelledTree a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabelledTree a -> (a, String)
rec where
rec :: LabelledTree a -> (a, String)
rec (Leaf String
l a
x) = (a
x, String
l String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ String
" " String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ a -> String
forall a. Show a => a -> String
show a
x)
rec (Branch String
l [LabelledTree a]
ts) = (a
x, String
l String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ String
" " String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ a -> String
forall a. Show a => a -> String
show a
x String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ String
"\n" String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ String -> String
indent ([String] -> String
unlines [String]
ls)) where
x :: a
x = (a -> a -> a) -> a -> [a] -> a
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> a -> a
combine a
init [a]
xs
([a]
xs, [String]
ls) = [(a, String)] -> ([a], [String])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(a, String)] -> ([a], [String]))
-> [(a, String)] -> ([a], [String])
forall a b. (a -> b) -> a -> b
$ (LabelledTree a -> (a, String))
-> [LabelledTree a] -> [(a, String)]
forall a b. (a -> b) -> [a] -> [b]
map LabelledTree a -> (a, String)
rec [LabelledTree a]
ts
indent :: String -> String
indent String
str = [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
indentation Char
' ' String -> String -> String
forall α. [α] -> [α] -> [α]
⧺) (String -> [String]
lines String
str)
unlines :: [String] -> String
unlines [] = String
""
unlines [String
x] = String
x
unlines [String]
xs = [String] -> String
forall a. HasCallStack => [a] -> a
head [String]
xs String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ String
"\n" String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ [String] -> String
unlines ([String] -> [String]
forall a. HasCallStack => [a] -> [a]
tail [String]
xs)
instance Show a ⇒ Show (LabelledTree a) where
show :: LabelledTree a -> String
show (Leaf String
l a
x) = String
l String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ String
" " String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ a -> String
forall a. Show a => a -> String
show a
x
show (Branch String
l [LabelledTree a]
s) = String
l String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ String
"\n" String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ String -> String
indent ([String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (LabelledTree a -> String) -> [LabelledTree a] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map LabelledTree a -> String
forall a. Show a => a -> String
show [LabelledTree a]
s) where
indent :: String -> String
indent String
str = [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
2 Char
' ' String -> String -> String
forall α. [α] -> [α] -> [α]
⧺) (String -> [String]
lines String
str)
unlines :: [String] -> String
unlines [] = String
""
unlines [String
x] = String
x
unlines [String]
xs = [String] -> String
forall a. HasCallStack => [a] -> a
head [String]
xs String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ String
"\n" String -> String -> String
forall α. [α] -> [α] -> [α]
⧺ [String] -> String
unlines ([String] -> [String]
forall a. HasCallStack => [a] -> [a]
tail [String]
xs)
redisplay ∷ Window → IO ()
redisplay :: Window -> IO ()
redisplay = Maybe Window -> IO ()
forall (m :: * -> *). MonadIO m => Maybe Window -> m ()
postRedisplay (Maybe Window -> IO ())
-> (Window -> Maybe Window) -> Window -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Window -> Maybe Window
forall a. a -> Maybe a
Just
readGraph :: IORef (GlobalVars n) -> IO (Graph n)
readGraph = (GlobalVars n -> Graph n) -> IO (GlobalVars n) -> IO (Graph n)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GlobalVars n -> Graph n
forall n. GlobalVars n -> Graph n
graph (IO (GlobalVars n) -> IO (Graph n))
-> (IORef (GlobalVars n) -> IO (GlobalVars n))
-> IORef (GlobalVars n)
-> IO (Graph n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef
writeGraph :: Graph n -> IORef (GlobalVars n) -> IO ()
writeGraph Graph n
g = (Graph n -> Graph n) -> IORef (GlobalVars n) -> IO ()
forall {n}. (Graph n -> Graph n) -> IORef (GlobalVars n) -> IO ()
modifyGraph (Graph n -> Graph n -> Graph n
forall a b. a -> b -> a
const Graph n
g)
modifyGraph :: (Graph n -> Graph n) -> IORef (GlobalVars n) -> IO ()
modifyGraph Graph n -> Graph n
f IORef (GlobalVars n)
globalVars = do
IORef (GlobalVars n) -> (GlobalVars n -> GlobalVars n) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef (GlobalVars n)
globalVars ((GlobalVars n -> GlobalVars n) -> IO ())
-> (GlobalVars n -> GlobalVars n) -> IO ()
forall a b. (a -> b) -> a -> b
$ \GlobalVars n
v → GlobalVars n
v {graph = f $ graph v}
applyRule ∷ Rule n → IORef (GlobalVars n) → IO ()
applyRule :: forall n. Rule n -> IORef (GlobalVars n) -> IO ()
applyRule Rule n
r IORef (GlobalVars n)
globalVars = do
Node -> Rewrite n ()
layout ← GlobalVars n -> Node -> Rewrite n ()
forall n. GlobalVars n -> Node -> Rewrite n ()
layoutStep (GlobalVars n -> Node -> Rewrite n ())
-> IO (GlobalVars n) -> IO (Node -> Rewrite n ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
Graph n
g ← IORef (GlobalVars n) -> IO (Graph n)
forall {n}. IORef (GlobalVars n) -> IO (Graph n)
readGraph IORef (GlobalVars n)
globalVars
let ns :: [Node]
ns = Rewrite n [Node] -> Graph n -> [Node]
forall n a. Rewrite n a -> Graph n -> a
evalGraph Rewrite n [Node]
forall n (m :: * -> *). MonadReader (Graph n) m => m [Node]
readNodeList Graph n
g
let (()
_, Graph n
g') = Rewrite n () -> Graph n -> ((), Graph n)
forall n a. Rewrite n a -> Graph n -> (a, Graph n)
runGraph (Rule n -> Rewrite n ()
forall n. Rule n -> Rewrite n ()
apply Rule n
r) Graph n
g
let ns' :: [Node]
ns' = Rewrite n [Node] -> Graph n -> [Node]
forall n a. Rewrite n a -> Graph n -> a
evalGraph Rewrite n [Node]
forall n (m :: * -> *). MonadReader (Graph n) m => m [Node]
readNodeList Graph n
g'
let newNodes :: [Node]
newNodes = [Node]
ns' [Node] -> [Node] -> [Node]
forall a. Eq a => [a] -> [a] -> [a]
Data.List.\\ [Node]
ns
Graph n -> IORef (GlobalVars n) -> IO ()
forall {n}. Graph n -> IORef (GlobalVars n) -> IO ()
writeGraph (Rewrite n () -> Graph n -> Graph n
forall n a. Rewrite n a -> Graph n -> Graph n
execGraph (Int -> Rewrite n [()] -> Rewrite n ()
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
15 (Rewrite n [()] -> Rewrite n ()) -> Rewrite n [()] -> Rewrite n ()
forall a b. (a -> b) -> a -> b
$ (Node -> Rewrite n ()) -> [Node] -> Rewrite n [()]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Node -> Rewrite n ()
layout [Node]
newNodes) Graph n
g') IORef (GlobalVars n)
globalVars
IORef (GlobalVars n) -> IO ()
forall {n}. IORef (GlobalVars n) -> IO ()
highlight IORef (GlobalVars n)
globalVars
selectRule :: Int -> IORef (GlobalVars n) -> IO ()
selectRule Int
i IORef (GlobalVars n)
globalVars = do
Int
ruleListLength ← LabelledTree (Int, Rule n) -> Int
forall a. LabelledTree a -> Int
numNodes (LabelledTree (Int, Rule n) -> Int)
-> (GlobalVars n -> LabelledTree (Int, Rule n))
-> GlobalVars n
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalVars n -> LabelledTree (Int, Rule n)
forall n. GlobalVars n -> RuleTree n
getRules (GlobalVars n -> Int) -> IO (GlobalVars n) -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
0 Int -> Int -> Bool
forall α. Ord α => α -> α -> Bool
≤ Int
i Bool -> Bool -> Bool
∧ Int
i Int -> Int -> Bool
forall α. Ord α => α -> α -> Bool
< Int
ruleListLength) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
IORef (GlobalVars n) -> (GlobalVars n -> GlobalVars n) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef (GlobalVars n)
globalVars ((GlobalVars n -> GlobalVars n) -> IO ())
-> (GlobalVars n -> GlobalVars n) -> IO ()
forall a b. (a -> b) -> a -> b
$ \GlobalVars n
v → GlobalVars n
v {selectedRule = i}
IORef (GlobalVars n) -> IO ()
forall {n}. IORef (GlobalVars n) -> IO ()
highlight IORef (GlobalVars n)
globalVars
highlight :: IORef (GlobalVars n) -> IO ()
highlight IORef (GlobalVars n)
globalVars = do
gv :: GlobalVars n
gv@GlobalVars {graph :: forall n. GlobalVars n -> Graph n
graph = Graph n
g, getRules :: forall n. GlobalVars n -> RuleTree n
getRules = RuleTree n
rs, selectedRule :: forall n. GlobalVars n -> Int
selectedRule = Int
r, highlighted :: forall n. GlobalVars n -> Set Node
highlighted = Set Node
h, canvas :: forall n. GlobalVars n -> Window
canvas = Window
c} ← IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
let rule :: Rule n
rule = ((Int, Rule n) -> Rule n) -> RuleTree n -> Rule n
forall m a. Monoid m => (a -> m) -> LabelledTree a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Int, Rule n) -> Rule n
forall a b. (a, b) -> b
snd (RuleTree n -> [RuleTree n]
forall a. LabelledTree a -> [LabelledTree a]
subtrees RuleTree n
rs [RuleTree n] -> Int -> RuleTree n
forall a. HasCallStack => [a] -> Int -> a
!! Int
r)
let h' :: Set Node
h' = [Node] -> Set Node
forall a. Ord a => [a] -> Set a
Set.fromList [[Node] -> Node
forall a. HasCallStack => [a] -> a
head [Node]
match | ([Node]
match,Rewrite n ()
rewrite) ← Rule n -> Graph n -> [([Node], Rewrite n ())]
forall n a. Pattern n a -> Graph n -> [([Node], a)]
runPattern Rule n
rule Graph n
g]
IORef (GlobalVars n) -> GlobalVars n -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (GlobalVars n)
globalVars (GlobalVars n -> IO ()) -> GlobalVars n -> IO ()
forall a b. (a -> b) -> a -> b
$ GlobalVars n
gv {highlighted = h'}
Window -> IO ()
redisplay Window
c
layoutLoop :: IORef (GlobalVars n) -> IO ()
layoutLoop IORef (GlobalVars n)
globalVars = do
gv :: GlobalVars n
gv@GlobalVars {graph :: forall n. GlobalVars n -> Graph n
graph = Graph n
g, paused :: forall n. GlobalVars n -> Bool
paused = Bool
p, layoutStep :: forall n. GlobalVars n -> Node -> Rewrite n ()
layoutStep = Node -> Rewrite n ()
l, canvas :: forall n. GlobalVars n -> Window
canvas = Window
c} ← IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
globalVars
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
p (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
(Position -> Vector2) -> n -> Vector2
forall v n field. View v n => (v -> field) -> n -> field
examine Position -> Vector2
position ([n] -> n
forall a. HasCallStack => [a] -> a
head ([n] -> n) -> [n] -> n
forall a b. (a -> b) -> a -> b
$ Graph n -> [n]
forall n. Graph n -> [n]
nodes Graph n
g) Vector2 -> IO () -> IO ()
forall a b. a -> b -> b
`seq` () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
IORef (GlobalVars n) -> GlobalVars n -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (GlobalVars n)
globalVars (GlobalVars n -> IO ()) -> GlobalVars n -> IO ()
forall a b. (a -> b) -> a -> b
$ GlobalVars n
gv {graph = execGraph (mapM l =<< readNodeList) g}
Window -> IO ()
redisplay Window
c
Int -> IO () -> IO ()
addTimerCallback Int
40 (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ IORef (GlobalVars n) -> IO ()
layoutLoop IORef (GlobalVars n)
globalVars
pause :: IORef (GlobalVars n) -> IO ()
pause IORef (GlobalVars n)
globalVars = IORef (GlobalVars n) -> (GlobalVars n -> GlobalVars n) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef (GlobalVars n)
globalVars ((GlobalVars n -> GlobalVars n) -> IO ())
-> (GlobalVars n -> GlobalVars n) -> IO ()
forall a b. (a -> b) -> a -> b
$ \GlobalVars n
vs → GlobalVars n
vs {paused = True}
resume :: IORef (GlobalVars n) -> IO ()
resume IORef (GlobalVars n)
globalVars = do
IORef (GlobalVars n) -> (GlobalVars n -> GlobalVars n) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef (GlobalVars n)
globalVars ((GlobalVars n -> GlobalVars n) -> IO ())
-> (GlobalVars n -> GlobalVars n) -> IO ()
forall a b. (a -> b) -> a -> b
$ \GlobalVars n
vs → GlobalVars n
vs {paused = False}
IORef (GlobalVars n) -> IO ()
forall {n}. View Position n => IORef (GlobalVars n) -> IO ()
layoutLoop IORef (GlobalVars n)
globalVars
subtrees ∷ LabelledTree a → [LabelledTree a]
subtrees :: forall a. LabelledTree a -> [LabelledTree a]
subtrees LabelledTree a
t = LabelledTree a
t LabelledTree a -> [LabelledTree a] -> [LabelledTree a]
forall a. a -> [a] -> [a]
: case LabelledTree a
t of
Leaf String
_ a
_ → []
Branch String
l [LabelledTree a]
ts → (LabelledTree a -> [LabelledTree a])
-> [LabelledTree a] -> [LabelledTree a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap LabelledTree a -> [LabelledTree a]
forall a. LabelledTree a -> [LabelledTree a]
subtrees [LabelledTree a]
ts
numNodes ∷ LabelledTree a → Int
numNodes :: forall a. LabelledTree a -> Int
numNodes = [LabelledTree a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([LabelledTree a] -> Int)
-> (LabelledTree a -> [LabelledTree a]) -> LabelledTree a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabelledTree a -> [LabelledTree a]
forall a. LabelledTree a -> [LabelledTree a]
subtrees
type RuleTree n = LabelledTree (Int, Rule n)
applyLeafRules ∷ (Rule n → Rule n) → Int → IORef (GlobalVars n) → IO ()
applyLeafRules :: forall n.
(Rule n -> Rule n) -> Int -> IORef (GlobalVars n) -> IO ()
applyLeafRules Rule n -> Rule n
restriction Int
idx IORef (GlobalVars n)
gvs = do
Graph n
g ← IORef (GlobalVars n) -> IO (Graph n)
forall {n}. IORef (GlobalVars n) -> IO (Graph n)
readGraph IORef (GlobalVars n)
gvs
RuleTree n
comptree ← GlobalVars n -> RuleTree n
forall n. GlobalVars n -> RuleTree n
getRules (GlobalVars n -> RuleTree n)
-> IO (GlobalVars n) -> IO (RuleTree n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
gvs
let pos :: Maybe (LTLoc (Int, Rule n))
pos = Int -> LTLoc (Int, Rule n) -> Maybe (LTLoc (Int, Rule n))
forall a. Int -> LTLoc a -> Maybe (LTLoc a)
nth Int
idx (RuleTree n -> LTLoc (Int, Rule n)
forall a. LabelledTree a -> LTLoc a
root RuleTree n
comptree)
case Maybe (LTLoc (Int, Rule n))
pos of
Maybe (LTLoc (Int, Rule n))
Nothing → () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just (RuleTree n
tree,LTZipper (Int, Rule n)
p) → do
let ns :: [Node]
ns = Rewrite n [Node] -> Graph n -> [Node]
forall n a. Rewrite n a -> Graph n -> a
evalGraph Rewrite n [Node]
forall n (m :: * -> *). MonadReader (Graph n) m => m [Node]
readNodeList Graph n
g
let rule :: Rule n
rule = Rule n -> Rule n
restriction (Rule n -> Rule n) -> Rule n -> Rule n
forall a b. (a -> b) -> a -> b
$ ((Int, Rule n) -> Rule n) -> RuleTree n -> Rule n
forall m a. Monoid m => (a -> m) -> LabelledTree a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Int, Rule n) -> Rule n
forall a b. (a, b) -> b
snd RuleTree n
tree
let ms :: [[Node]]
ms = [[[Node]]] -> [[Node]]
forall a. HasCallStack => [a] -> a
head ([[[Node]]] -> [[Node]]) -> [[[Node]]] -> [[Node]]
forall a b. (a -> b) -> a -> b
$ Pattern n [[Node]] -> Graph n -> [[[Node]]]
forall n a. Pattern n a -> Graph n -> [a]
evalPattern (Rule n -> Pattern n [[Node]]
forall (m :: * -> *) n a.
Monad m =>
PatternT n m a -> PatternT n m [[Node]]
matches Rule n
rule) Graph n
g
let (([[Node]]
_, Graph n
g'), RuleTree n
tree') = (([[Node]], Graph n)
-> (Int, Rule n) -> (([[Node]], Graph n), (Int, Rule n)))
-> ([[Node]], Graph n)
-> RuleTree n
-> (([[Node]], Graph n), RuleTree n)
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL ([[Node]], Graph n)
-> (Int, Rule n) -> (([[Node]], Graph n), (Int, Rule n))
forall {a}.
Num a =>
([[Node]], Graph n)
-> (a, Rule n) -> (([[Node]], Graph n), (a, Rule n))
applyLeafRules' ([[Node]]
ms, Graph n
g) RuleTree n
tree
let ns' :: [Node]
ns' = Rewrite n [Node] -> Graph n -> [Node]
forall n a. Rewrite n a -> Graph n -> a
evalGraph Rewrite n [Node]
forall n (m :: * -> *). MonadReader (Graph n) m => m [Node]
readNodeList Graph n
g'
let newNodes :: [Node]
newNodes = [Node]
ns' [Node] -> [Node] -> [Node]
forall a. Eq a => [a] -> [a] -> [a]
Data.List.\\ [Node]
ns
Node -> Rewrite n ()
layout ← GlobalVars n -> Node -> Rewrite n ()
forall n. GlobalVars n -> Node -> Rewrite n ()
layoutStep (GlobalVars n -> Node -> Rewrite n ())
-> IO (GlobalVars n) -> IO (Node -> Rewrite n ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef (GlobalVars n) -> IO (GlobalVars n)
forall a. IORef a -> IO a
readIORef IORef (GlobalVars n)
gvs
Graph n -> IORef (GlobalVars n) -> IO ()
forall {n}. Graph n -> IORef (GlobalVars n) -> IO ()
writeGraph (Rewrite n () -> Graph n -> Graph n
forall n a. Rewrite n a -> Graph n -> Graph n
execGraph (Int -> Rewrite n [()] -> Rewrite n ()
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
15 ((Node -> Rewrite n ()) -> [Node] -> Rewrite n [()]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Node -> Rewrite n ()
layout [Node]
newNodes)) Graph n
g') IORef (GlobalVars n)
gvs
IORef (GlobalVars n) -> (GlobalVars n -> GlobalVars n) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef (GlobalVars n)
gvs ((GlobalVars n -> GlobalVars n) -> IO ())
-> (GlobalVars n -> GlobalVars n) -> IO ()
forall a b. (a -> b) -> a -> b
$ \GlobalVars n
x → GlobalVars n
x {getRules = fst $ top (tree',p)}
where
applyLeafRules' :: ([[Node]], Graph n)
-> (a, Rule n) -> (([[Node]], Graph n), (a, Rule n))
applyLeafRules' ([[Node]]
matches, Graph n
g) (a
n, Rule n
r) = let
ms :: [([Node], Rewrite n ())]
ms = Rule n -> Graph n -> [([Node], Rewrite n ())]
forall n a. Pattern n a -> Graph n -> [([Node], a)]
runPattern Rule n
r' Graph n
g
r' :: Rule n
r' = ([Node] -> [Node] -> Bool) -> Rule n -> Rule n
forall (m :: * -> *) n a.
Monad m =>
([Node] -> [Node] -> Bool) -> PatternT n m a -> PatternT n m a
restrictOverlap (\[Node]
past [Node]
future → [Node]
future [Node] -> [[Node]] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Node]]
matches) (Rule n -> Rule n
restriction Rule n
r)
in if [([Node], Rewrite n ())] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [([Node], Rewrite n ())]
ms
then (([[Node]]
matches, Graph n
g), (a
n, Rule n
r))
else let
([Node]
match, Rewrite n ()
rewrite) = [([Node], Rewrite n ())] -> ([Node], Rewrite n ())
forall a. HasCallStack => [a] -> a
head [([Node], Rewrite n ())]
ms
g' :: Graph n
g' = Rewrite n () -> Graph n -> Graph n
forall n a. Rewrite n a -> Graph n -> Graph n
execGraph Rewrite n ()
rewrite Graph n
g
in ([[Node]], Graph n)
-> (a, Rule n) -> (([[Node]], Graph n), (a, Rule n))
applyLeafRules' (([Node] -> Bool) -> [[Node]] -> [[Node]]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> ([Node] -> Bool) -> [Node] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Node -> Bool) -> [Node] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Node -> [Node] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Node]
match)) [[Node]]
matches, Graph n
g') (a
n a -> a -> a
forall a. Num a => a -> a -> a
+ a
1, Rule n
r)