-
Notifications
You must be signed in to change notification settings - Fork 1
/
MainParsing.hs
330 lines (288 loc) · 9.09 KB
/
MainParsing.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE QualifiedDo #-}
{-# OPTIONS_GHC -Wno-all #-}
module Main where
import ChartParser
import Common
import Display
import GreedyParser as Greedy
import PVGrammar
import PVGrammar.Generate
import PVGrammar.Parse
import PVGrammar.Prob.Simple
( observeDerivation
, sampleDerivation
)
import Musicology.Core
import Musicology.Core.Slicing
-- import Musicology.Internal.Helpers
import Musicology.MusicXML
import Musicology.Pitch.Spelled as MT
import Data.Either (partitionEithers)
import Data.Maybe (catMaybes)
import Data.Ratio (Ratio (..))
import Lens.Micro (over)
import Control.Monad
( foldM
, forM
, forM_
)
import Control.Monad.Except (runExceptT)
import Data.HashSet qualified as HS
import Data.List qualified as L
import Data.Semiring qualified as R
import Data.Sequence qualified as Seq
import Data.Set qualified as S
import Data.Text qualified as T
import Data.Text.IO qualified as T
import Data.Text.Lazy qualified as TL
import Data.Text.Lazy.IO qualified as TL
import Internal.MultiSet qualified as MS
import Control.DeepSeq
( deepseq
, force
)
import Control.Monad.Trans.Maybe (MaybeT (MaybeT))
import Data.Bifunctor (Bifunctor (bimap))
import Data.String (fromString)
import Inference.Conjugate
( runTrace
, showTrace
, traceTrace
)
-- better do syntax
import Language.Haskell.DoNotation qualified as Do
-- import Prelude hiding ( Monad(..)
-- , pure
-- )
-- utilities
-- =========
-- reading files
-- -------------
testfile = "testdata/allemande.musicxml"
bb =
"/home/chfin/dateien/dev/haskell/work/proto-voice-model/bluebossa.musicxml"
brahms1 =
"/home/chfin/dateien/dev/haskell/work/proto-voice-model/brahms1.musicxml"
haydn5 = "/home/chfin/Uni/phd/data/kirlin_schenker/haydn5.xml"
invention =
"/home/chfin/Uni/phd/data/protovoice-annotations/bach/inventions/BWV_0784.musicxml"
-- getPitchGroups :: FilePath -> IO [[OnOff SPitch (Ratio Int)]]
-- getPitchGroups file = do
-- txt <- TL.readFile file
-- return
-- $ fmap (fmap $ over onOffContent pitch)
-- $ onOffGroups
-- $ asNote
-- <$> xmlNotesHeard txt
testslices = loadSurface' testfile
-- manual inputs
-- -------------
monopath :: [a] -> Path [a] [b]
monopath = path . fmap (: [])
path :: [a] -> Path a [b]
path [] = error "cannot construct empty path"
path [a] = PathEnd a
path (a : as) = Path a [] $ path as
-- actions
-- -------
printDerivs path = do
ds <- parseSilent pvDerivRightBranch path
forM_ (flattenDerivations ds) $ \d -> do
putStrLn "\nDerivation:"
forM_ d $ \step -> do
putStrLn $ "- " <> show step
case replayDerivation derivationPlayerPV d of
Left error -> putStrLn $ "Error: " <> error
Right _ -> putStrLn "Ok."
plotDerivs fn derivs = do
pics <- forM derivs $ \d -> case replayDerivation derivationPlayerPV d of
Left error -> do
putStrLn error
print d
return Nothing
Right g -> return $ Just g
viewGraphs fn $ catMaybes pics
plotDeriv fn deriv = do
case replayDerivation derivationPlayerPV deriv of
(Left err) -> putStrLn err
(Right g) -> viewGraph fn g
plotSteps fn deriv = do
let graphs = unfoldDerivation derivationPlayerPV deriv
(errors, steps) = partitionEithers graphs
mapM_ putStrLn errors
viewGraphs fn $ reverse steps
checkDeriv deriv original = do
case replayDerivation derivationPlayerPV deriv of
(Left err) -> putStrLn err
(Right g) -> do
let path' = case dgFrozen g of
(_ : (_, tlast, slast) : rst) -> do
s <- getInner $ dslContent slast
foldM foldPath (PathEnd s, tlast) rst
_ -> Nothing
orig' =
bimap
(Notes . MS.fromList)
(\e -> Edges (HS.fromList e) MS.empty)
original
case path' of
Nothing -> putStrLn "failed to check result path"
Just (result, _) ->
if result == orig'
then putStrLn "roundtrip ok"
else do
putStrLn "roundtrip not ok, surfaces are not equal:"
putStrLn "original:"
print original
putStrLn "recreated:"
print result
where
foldPath (pacc, tacc) (_, tnew, snew) = do
s <- getInner $ dslContent snew
pure (Path s tacc pacc, tnew)
-- example derivations
-- ===================
derivBrahms :: [PVLeftmost (Pitch MT.SIC)]
derivBrahms = buildDerivation $ Do.do
split $ mkSplit $ do
splitRegular Start Stop (c' shp) RootNote False False
splitRegular Start Stop (a' nat) RootNote False False
spread $ mkSpread $ do
spreadNote (a' nat) ToBoth True
spreadNote (c' shp) (ToLeft 1) False
addPassing (c' shp) (a' nat)
splitRight $ mkSplit $ do
splitPassing (c' shp) (a' nat) (b' nat) PassingMid False False
splitRegular (Inner $ a' nat) (Inner $ a' nat) (g' shp) FullNeighbor False False
spread $ mkSpread $ do
spreadNote (a' nat) (ToRight 1) False
spreadNote (c' shp) (ToLeft 1) False
addPassing (c' shp) (a' nat)
freeze FreezeOp
split $ mkSplit $ do
splitPassing (c' shp) (a' nat) (b' nat) PassingMid False False
freeze FreezeOp
freeze FreezeOp
spread $ mkSpread $ do
spreadNote (b' nat) (ToRight 1) False
spreadNote (g' shp) (ToLeft 1) False
split $ mkSplit $ do
addToRight (g' shp) (a' nat) LeftNeighbor False
freeze FreezeOp
freeze FreezeOp
split $ mkSplit $ do
addToRight (b' nat) (c' shp) LeftNeighbor False
freeze FreezeOp
freeze FreezeOp
freeze FreezeOp
freeze FreezeOp
where
(>>) :: Do.BindSyntax x y z => x a -> y b -> z b
(>>) = (Do.>>)
-- mains
-- =====
mainGreedy file = do
input <- loadSurface file
print input
result <- runExceptT $ Greedy.parseRandom protoVoiceEvaluator input
case result of
Left err -> print err
-- Right _ -> putStrLn "Ok."
Right (Analysis deriv top) -> do
print "done parsing."
checkDeriv deriv input
case replayDerivation derivationPlayerPV deriv of
Left err -> putStrLn err
Right g -> viewGraph "greedy.tex" g
-- case observeDerivation deriv top of
-- Left err -> print err
-- Right trace -> do
-- print "done observing parse."
-- putStrLn
-- $ "trace has "
-- <> show (Seq.length (runTrace trace))
-- <> " items."
-- -- let res = traceTrace trace (sampleDerivation top)
-- -- pure ()
forM_ deriv print
mainCount fn = do
input <- loadSurface fn
print input
count <- parseSize pvCountNoRepSplitRightBranchSplitFirst input
putStrLn $ show count <> " derivations"
mainTest from to = do
putStrLn $ "slices " <> show from <> " to " <> show to
input <- testslices from to
print input
count <- parseSize pvCountNoRepSplitRightBranchSplitFirst input
putStrLn $ show count <> " derivations"
mainBB = do
input <- slicesToPath <$> slicesFromFile bb
print input
count <- parseSize pvCountNoRepSplitRightBranchSplitFirst input
print count
mainBrahms = do
input <- slicesToPath <$> slicesFromFile brahms1
print input
count <- parseSize pvCountNoRepSplitRightBranchSplitFirst input
print count
mainGraph = do
input <- slicesToPath <$> slicesFromFile brahms1
derivs <- parseSize pvDerivRightBranch input
let ds = S.toList $ flattenDerivations derivs
pics <- forM ds $ \d -> case replayDerivation derivationPlayerPV d of
Left err -> do
putStrLn err
print d
return Nothing
Right g -> return $ Just g
print pics
viewGraphs "brahms.tex" $ catMaybes pics
logFull tc vc n = do
putStrLn "\n===========\n"
putStrLn $ "level " <> show n
putStrLn "\ntransitions:"
mapM_ print $ tcGetByLength tc n
putStrLn "\nverticalizations:"
mapM_ print $ vcGetByLength vc (n - 1)
mainResult
:: Parsable e a v
=> Eval e [Edge (Pitch SInterval)] a [Pitch SInterval] v
-> Int
-> Int
-> IO v
mainResult evaluator from to = do
putStrLn $ "slices " <> show from <> " to " <> show to
input <- testslices from to
parseSize evaluator input
parseHaydn :: _ => _ -> IO r
parseHaydn eval = do
slices <- slicesFromFile haydn5
parseSize eval $ slicesToPath $ take 9 slices
mainHaydn = do
slices <- slicesFromFile haydn5
derivs <- parseSize pvCountNoRepSplitRightBranchSplitFirst $ slicesToPath $ take 8 slices
print derivs
putStrLn "done."
mainRare = do
slices <- slicesFromFile "data/theory-article/10c_rare_int.musicxml"
putStrLn "\\documentclass[tikz]{standalone}"
putStrLn "\\usetikzlibrary{calc,positioning}"
putStrLn "\\tikzstyle{slice} = []"
putStrLn "\\tikzstyle{transition} = []"
putStrLn "\\begin{document}"
putStrLn "\\begin{tikzpicture}[xscale=4,yscale=1]"
derivs <- parse logTikz pvDerivUnrestricted $ slicesToPath slices
putStrLn "\\end{tikzpicture}"
putStrLn "\\end{document}"
-- pure ()
let ds = S.toList $ flattenDerivations derivs
pics <- forM ds $ \d -> case replayDerivation derivationPlayerPVAllEdges d of
Left err -> do
putStrLn err
print d
return Nothing
Right g -> return $ Just g
viewGraphs "rare.tex" $ catMaybes pics
main = mainRare