sourcework/xetal-libraries/libs/Graphs/src/Graphs.xtlm

1⍝│ Graphs: its macro library -- g_raph<, a graph written by its names. 2⍝│ Imported with the functions, under one alias: "g:" u_se< "Graphs". 3⍝│ A macro is a function from the source text written left and right of 4⍝│ its call to the source that replaces the call, run before the program 5⍝│ is compiled (X_eTaL MC10). Names with m: are macros; those under h: are 6⍝│ private to this file. 7 8"t:" u̲se< "Strings" 9"pa:" u̲se< "Parsing" 10 11⍝━━ Parsing 12 13⍝│ The lists of a list joined into one list. 14ʰr̲aze ← { b → d̲isclose '{ e̲nclose (d̲isclose ⍺) c̲at d̲isclose ⍵ } r̲/ b } 15 16⍝│ The paths of a graph text: a list per path, its stations in order, 17⍝│ cut at the commas and dashes outside brackets (Parsing's pa:s_plit, 18⍝│ as any list here is). 19ʰp̲aths ← { t → '{ p → '{ s → ᵗt̲rim d̲isclose s } m̲ap "-" ᵖᵃs̲plit ᵗt̲rim d̲isclose p } m̲ap "," ᵖᵃs̲plit t } 20 21⍝━━ The macro 22 23⍝│ "town" g:g_raph< "airport-bridge-center, center-docks": the graph 24⍝│ written by its names, paths of stations joined by "-", paths 25⍝│ separated by ",". When the program is compiled it defines a variable 26⍝│ per station, numbered in order of first appearance (airport := 1, 27⍝│ bridge := 2, ...), and town as the adjacency matrix, every edge both 28⍝│ ways, so the rest of the program speaks of stations by name 29⍝│ (town g:l_evels center). It stands as a statement of its own. A name 30⍝│ that cannot be a variable stops the compiler at it: error[bad-name]. 31⍝│ takes: text text 32⍝│ uses: parsed 33ᵐg̲raph< ← { name t → 34 ps ← ʰp̲aths t 35 stations ← u̲nique ʰr̲aze ps 36 n̲ot ᵖᵃn̲ame? name ? "bad-name left" ⎕R̲EJECT name c̲at " cannot be a variable's name: a lowercase letter, then letters and digits" 37 bad ← (n̲ot '{ ᵖᵃn̲ame? d̲isclose ⍵ } e̲ach stations) r̲eplicate stations 38 0 < t̲ally bad ? "bad-name right" ⎕R̲EJECT (d̲isclose f̲irst bad) c̲at " cannot be a station's name: a lowercase letter, then letters and digits" 39 n ← t̲ally stations 40 ⍝ each station's number, path by path; neighbors on a path are edges 41 ks ← '{ p → stations i̲ndexOf d̲isclose p } m̲ap ps 42 a ← ʰr̲aze '{ k → -1 d̲rop d̲isclose k } m̲ap ks 43 b ← ʰr̲aze '{ k → 1 d̲rop d̲isclose k } m̲ap ks 44 from ← a c̲at b ⍝ both ways 45 to ← b c̲at a 46 at ← (n × from − 1) + to 47 m ← (r̲ange n × n) m̲ember? at 48 defs ← "\n" ᵗj̲oin '{ i → (d̲isclose i s̲elect stations) c̲at " := " c̲at f̲ormat i } m̲ap r̲ange n 49 defs c̲at "\n" c̲at name c̲at " := " c̲at (f̲ormat n) c̲at " " c̲at (f̲ormat n) c̲at " r_eshape " c̲at f̲ormat 0 + m 50}