From 8f52ba1bbd68bab90b13d47ec9ff636127337660 Mon Sep 17 00:00:00 2001 From: Henrik Tidefelt Date: Tue, 26 Jan 2016 09:47:09 +0100 Subject: [PATCH] Ammend merge: Fix examples and tests --- examples/applications/pinhole.shape | 2 +- examples/applications/sorting-performance.shape | 56 ++++++----- examples/doc/graph-state.shape | 11 +- examples/doc/graph-walk.shape | 25 +++-- examples/doc/graphs-bipartite.shape | 16 ++- examples/doc/graphs-circle-layout.shape | 14 ++- examples/doc/graphs-mixed.shape | 20 ++-- examples/doc/graphs-multigraph.shape | 22 ++-- examples/doc/remainders.shape | 2 +- examples/doc/tutorial-view.shape | 2 +- examples/features/folds.blank | 3 +- examples/features/graphs.shape | 111 +++++++++++---------- examples/features/hulls.shape | 2 + examples/features/intersections.shape | 2 + examples/features/lists.shape | 17 ++-- examples/misc/self.shape | 4 +- resources/extensions/Shapes/Data/seq-support.shext | 2 +- test/text/sort.shape | 22 ++-- 18 files changed, 193 insertions(+), 140 deletions(-) diff --git a/examples/applications/pinhole.shape b/examples/applications/pinhole.shape index 3c47836d..4379af09 100644 --- a/examples/applications/pinhole.shape +++ b/examples/applications/pinhole.shape @@ -92,7 +92,7 @@ p: [Layout..mspoint C--P f/P.z] •rayWorld << Traits..@nonstroking:Traits..BW..WHITE | [Graphics..fill imageFrame] •rayWorld << [Graphics..stroke imageFrame] } -rayWorld: •rayWorld; +rayWorld: freeze •rayWorld •world << rayWorld { base: [shift (0u,0u,f)] [] [baseVectors2D] diff --git a/examples/applications/sorting-performance.shape b/examples/applications/sorting-performance.shape index b6037d0c..09968d7f 100644 --- a/examples/applications/sorting-performance.shape +++ b/examples/applications/sorting-performance.shape @@ -16,8 +16,16 @@ ** Copyright 2014 Henrik Tidefelt **/ -##needs seq-support +##needs ..Shapes..Data / seq-support +##lookin ..Shapes +##lookin ..Shapes..Geometry +##lookin ..Shapes..Layout +##lookin ..Shapes..Traits +##lookin ..Shapes..Control +##lookin ..Shapes..Data +##lookin ..Shapes..Numeric..Random +##lookin ..Shapes..Numeric..Math /** Merge sort implemented in Shapes **/ @@ -70,7 +78,7 @@ mergeSort: randomList: { - helper: \ n res •rnd → [if (n = '0) res [helper (n - '1) (![random1D •rnd] ; res) •rnd]] + helper: \ n res •rnd → [if (n = '0) res [helper (n - '1) (![ball1D •rnd] ; res) •rnd]] \ n •rnd → [helper n nil •rnd] } @@ -115,22 +123,22 @@ xMap: \ x → ( xSize / [log xMax / xMin] ) * [log x / xMin] yMap: \ y → ( ySize / [log yMax / yMin] ) * [log y / yMin] dataLine: \ timeData → [timeData.foldl (\ s e → s--([xMap e.x], [yMap e.y])) emptypath] -mark: @width:0.1bp | [stroke [circle 1bp]] -dataMarks: \ timeData → [timeData.foldl (\ s e → s & [[shift ([xMap e.x], [yMap e.y])] mark]) null] +mark: @width:0.1bp | [Graphics..stroke [circle 1bp]] +dataMarks: \ timeData → [timeData.foldl (\ s e → s & [[shift ([xMap e.x], [yMap e.y])] mark]) Graphics..null] /** Draw axes **/ -•page << @width:0.3bp | [stroke (0m,0m)--(xSize, 0m) head:ShapesArrow] -•page << @width:0.3bp | [stroke (0m,0m)--(0m, ySize) head:ShapesArrow] +IO..•page << @width:0.3bp | [Graphics..stroke (0m,0m)--(xSize, 0m) head:Graphics..ShapesArrow] +IO..•page << @width:0.3bp | [Graphics..stroke (0m,0m)--(0m, ySize) head:Graphics..ShapesArrow] /** Linear axes **/ -|**•page << @width:0.3bp | [[range 0 0.95*xRange step:2000].cdr.foldl (\ s e → s & [[shift ([xMap e],0)] [stroke (0m,0m)--(0m,~1.5mm)] & [[shift (0,~5mm)] [center_x (newText << [sprintf `%g´ e])]]]) null] -|**•page << @width:0.3bp | [[range 0 0.95*yRange step:5].cdr.foldl (\ s e → s & [[shift (0,[yMap e])] [stroke (0m,0m)--(~1.5mm,0m)] & [[shift (~2mm,~0.4*@text_size)] [center_x (newText << [sprintf `%g´ e]) 1]]]) null] +|**IO..•page << @width:0.3bp | [[range 0 0.95*xRange step:2000].cdr.foldl (\ s e → s & [[shift ([xMap e],0)] [Graphics..stroke (0m,0m)--(0m,~1.5mm)] & [[shift (0,~5mm)] [center_x (Text..newText << [String..sprintf `%g´ e])]]]) Graphics..null] +|**IO..•page << @width:0.3bp | [[range 0 0.95*yRange step:5].cdr.foldl (\ s e → s & [[shift (0,[yMap e])] [Graphics..stroke (0m,0m)--(~1.5mm,0m)] & [[shift (~2mm,~0.4*Text..@size)] [center_x (Text..newText << [String..sprintf `%g´ e]) 1]]]) Graphics..null] /** Logarithmic axes **/ -•page << @width:0.3bp & @text_size:8bp | +IO..•page << @width:0.3bp & Text..@size:8bp | { [[range [floor [log10 xMin]] [ceil [log10 xMax]]].cdr.foldl \ s e → @@ -140,16 +148,16 @@ dataMarks: \ timeData → [timeData.foldl (\ s e → s & [[shift ([xMap e.x], [y val: [pow 10 e] * eSub c: [xMap val] [if xMin < val and val < xMax - s & [[shift (c,0)] [stroke (0m,0m)--(0m,~1.5mm)] & [[shift (0,~5mm)] [center_x (newText << [sprintf `%g´ val])]]] + s & [[shift (c,0)] [Graphics..stroke (0m,0m)--(0m,~1.5mm)] & [[shift (0,~5mm)] [center_x (Text..newText << [String..sprintf `%g´ val])]]] s ] } s ] - null + Graphics..null ] } -•page << @width:0.3bp & @text_size:8bp | +IO..•page << @width:0.3bp & Text..@size:8bp | { [[range [floor [log10 yMin]] [ceil [log10 yMax]]].cdr.foldl \ s e → @@ -159,37 +167,37 @@ dataMarks: \ timeData → [timeData.foldl (\ s e → s & [[shift ([xMap e.x], [y val: [pow 10 e] * eSub c: [yMap val] [if yMin < val and val < yMax - s & [[shift (0,c)] [stroke (0m,0m)--(~1.5mm,0m)] & [[shift (~2mm,~0.4*@text_size)] [center_x (newText << [sprintf `%g´ val]) 1]]] + s & [[shift (0,c)] [Graphics..stroke (0m,0m)--(~1.5mm,0m)] & [[shift (~2mm,~0.4*Text..@size)] [center_x (Text..newText << [String..sprintf `%g´ val]) 1]]] s ] } s ] - null + Graphics..null ] } -•dataView: newGroup +•dataView: Graphics..newGroup /** Draw the data. **/ { line: [dataLine timeData_lexiographicSort_random] - •dataView << @width:0.5bp | [stroke line] + •dataView << @width:0.5bp | [Graphics..stroke line] << [dataMarks timeData_lexiographicSort_random] - << [[shift [intersection line (0.6*xSize,0)--((+0cm),ySize)].p] [center_wlm (newText << `lexiographicSort´) (~1, 1)]] + << [[shift [intersection line (0.6*xSize,0)--((+0cm),ySize)].p] [center_wlm (Text..newText << `lexiographicSort´) (~1, 1)]] } { line: [dataLine timeData_sort_random] - •dataView << @width:0.5bp | [stroke line] + •dataView << @width:0.5bp | [Graphics..stroke line] << [dataMarks timeData_sort_random] - << [[shift [intersection line (0.55*xSize,0)--((+0cm),ySize)].p] [center_wlm (newText << `sort´) (1, ~1)]] + << [[shift [intersection line (0.55*xSize,0)--((+0cm),ySize)].p] [center_wlm (Text..newText << `sort´) (1, ~1)]] } { line: [dataLine timeData_mergeSort_random] - •dataView << @width:0.5bp | [stroke line] + •dataView << @width:0.5bp | [Graphics..stroke line] << [dataMarks timeData_mergeSort_random] - << [[shift [intersection line (0.3*xSize,0)--((+0cm),ySize)].p] [center_wlm (newText << `mergeSort´) (1, ~1)]] + << [[shift [intersection line (0.3*xSize,0)--((+0cm),ySize)].p] [center_wlm (Text..newText << `mergeSort´) (1, ~1)]] } /** Draw an n * log( n ) helper line. @@ -204,9 +212,9 @@ dataMarks: \ timeData → [timeData.foldl (\ s e → s & [[shift ([xMap e.x], [y } emptypath ] - •dataView << @width:0.5bp & @stroking:[gray 0.5] | [stroke line] - << [[shift [intersection line (0.65*xSize,0)--((+0cm),ySize)].p] [center_wlm [TeX [sprintf `$%g\, n\, \log(\, n \,)$´ c]] (1, ~1)]] + •dataView << @width:0.5bp & @stroking:[gray 0.5] | [Graphics..stroke line] + << [[shift [intersection line (0.65*xSize,0)--((+0cm),ySize)].p] [center_wlm [Graphics..TeX [String..sprintf `$%g\, n\, \log(\, n \,)$´ c]] (1, ~1)]] } dataView: freeze •dataView -•page << [clip dataView [rectangle (0m,0m) (xSize, ySize)]] +IO..•page << [Graphics..clip dataView [rectangle (0m,0m) (xSize, ySize)]] diff --git a/examples/doc/graph-state.shape b/examples/doc/graph-state.shape index 57daada0..d1b157be 100644 --- a/examples/doc/graph-state.shape +++ b/examples/doc/graph-state.shape @@ -16,7 +16,10 @@ ** Copyright 2014 Henrik Tidefelt **/ -##needs seq-support +##needs ..Shapes..Data / seq-support + +##lookin ..Shapes +##lookin ..Shapes..Data /** Helper function for converting a sequence to a string, with elements separated by spaces. **/ @@ -37,12 +40,12 @@ seq_sep_string: \ seq → [seq_string [separate ` ´ seq]] g1: freeze •dst -•stdout << `Edges in g1: ´ << [seq_sep_string g1.edges] << "{n} +IO..•stdout << `Edges in g1: ´ << [seq_sep_string g1.edges] << "{n} /** Add more nodes and edges using an unnamed state. **/ g2: ( g1 << >>.[node 'd] << >>.[edge 'c 'd] ) -•stdout << `Edges in g2: ´ << [seq_sep_string g2.edges] << "{n} +IO..•stdout << `Edges in g2: ´ << [seq_sep_string g2.edges] << "{n} /** Prevent empty output error. **/ -@spot +Graphics..@spot diff --git a/examples/doc/graph-walk.shape b/examples/doc/graph-walk.shape index cba7e66d..23959201 100644 --- a/examples/doc/graph-walk.shape +++ b/examples/doc/graph-walk.shape @@ -16,7 +16,10 @@ ** Copyright 2014 Henrik Tidefelt **/ -##needs seq-support +##needs ..Shapes..Data / seq-support + +##lookin ..Shapes +##lookin ..Shapes..Data /** Helper function for converting a sequence to a string, with elements separated by spaces. **/ @@ -43,15 +46,15 @@ w: [walk [list ] /** Examine the walk. **/ -•stdout << `Length of walk: ´ << w.edge_count << "{n} -•stdout << `Simple?: ´ << w.simple? << "{n} -•stdout << `Node cover?: ´ << w.node_cover? << "{n} -•stdout << `Edge cover?: ´ << w.edge_cover? << "{n} -•stdout << `Open or closed: ´ << [if w.open? `open´ `closed´] << "{n} -•stdout << `Edges in the walk: ´ << [seq_sep_string w.edges] << "{n} +IO..•stdout << `Length of walk: ´ << w.edge_count << "{n} +IO..•stdout << `Simple?: ´ << w.simple? << "{n} +IO..•stdout << `Node cover?: ´ << w.node_cover? << "{n} +IO..•stdout << `Edge cover?: ´ << w.edge_cover? << "{n} +IO..•stdout << `Open or closed: ´ << [if w.open? `open´ `closed´] << "{n} +IO..•stdout << `Edges in the walk: ´ << [seq_sep_string w.edges] << "{n} /** Visit all nodes along the walk. **/ -•stdout << `Node keys along the walk: ´ << w.start.key +IO..•stdout << `Node keys along the walk: ´ << w.start.key ignore [] [w.edges.foldsl \ n e •dst → { @@ -60,9 +63,9 @@ ignore [] [w.edges.foldsl next } w.start - •stdout + IO..•stdout ] -•stdout << "{n} +IO..•stdout << "{n} /** Prevent empty output error. **/ -@spot +Graphics..@spot diff --git a/examples/doc/graphs-bipartite.shape b/examples/doc/graphs-bipartite.shape index 6e9eae2b..b4e58115 100644 --- a/examples/doc/graphs-bipartite.shape +++ b/examples/doc/graphs-bipartite.shape @@ -16,7 +16,13 @@ ** Copyright 2014 Henrik Tidefelt **/ -##needs seq-support +##needs ..Shapes..Data / seq-support + +##lookin ..Shapes +##lookin ..Shapes..Data +##lookin ..Shapes..Geometry +##lookin ..Shapes..Layout +##lookin ..Shapes..Graphics /** Graph layout function for bipartite graphs. ** (Ignoring any previous content of node values.) @@ -53,14 +59,14 @@ bipartiteGraphLayout: \ g partitionSep:5cm nodeSep:1cm → **/ renderBipartiteGraph: \ g → { - nodeRadius: 0.75*@text_size + nodeRadius: 0.75*Text..@size leftKey: [seq_index '0 g.partitions] /** A circle at each node **/ - nodeCircles: @width:3*@width | [g.nodes.foldl \ s n → (s & ( @stroking:[if n.partition = leftKey RGB_RED RGB_GREEN] | [[shift n.value.coords] stroke[][circle nodeRadius]] ) ) null] + nodeCircles: Traits..@width:3*Traits..@width | [g.nodes.foldl \ s n → (s & ( Traits..@stroking:[if n.partition = leftKey Traits..RGB..RED Traits..RGB..GREEN] | [[shift n.value.coords] stroke[][circle nodeRadius]] ) ) null] /** the node keys **/ - nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (newText << (newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) null] + nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (Text..newText << (String..newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) null] /** Stroke the edges **/ edgePath: \ e → @@ -87,4 +93,4 @@ g: [graph undirected:true partitions:[list 'left 'right] /** Apply layout and rendering functions. **/ -@text_size:9bp & @width:0.3bp | [renderBipartiteGraph [bipartiteGraphLayout g]] +Text..@size:9bp & Traits..@width:0.3bp | [renderBipartiteGraph [bipartiteGraphLayout g]] diff --git a/examples/doc/graphs-circle-layout.shape b/examples/doc/graphs-circle-layout.shape index e1653cf4..6d6b2928 100644 --- a/examples/doc/graphs-circle-layout.shape +++ b/examples/doc/graphs-circle-layout.shape @@ -16,7 +16,13 @@ ** Copyright 2014 Henrik Tidefelt **/ -##needs seq-support +##needs ..Shapes..Data / seq-support + +##lookin ..Shapes +##lookin ..Shapes..Data +##lookin ..Shapes..Geometry +##lookin ..Shapes..Layout +##lookin ..Shapes..Graphics /** Graph layout function for nodes on a circle. ** (Ignoring any previous content of node values.) @@ -31,13 +37,13 @@ circleGraphLayout: \ g radius:3cm → **/ renderGraph: \ g → { - nodeRadius: 0.75*@text_size + nodeRadius: 0.75*Text..@size /** A circle at each node **/ nodeCircles: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] stroke[][circle nodeRadius]]) null] /** the node keys **/ - nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (newText << (newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) null] + nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (Text..newText << (String..newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) null] /** Stroke the edges **/ edgePath: \ e → @@ -62,4 +68,4 @@ g: [graph directed:true /** Apply layout and rendering functions. **/ -@text_size:9bp & @width:0.3bp | [renderGraph [circleGraphLayout g]] +Text..@size:9bp & Traits..@width:0.3bp | [renderGraph [circleGraphLayout g]] diff --git a/examples/doc/graphs-mixed.shape b/examples/doc/graphs-mixed.shape index f1c5088b..d50db208 100644 --- a/examples/doc/graphs-mixed.shape +++ b/examples/doc/graphs-mixed.shape @@ -16,7 +16,13 @@ ** Copyright 2014 Henrik Tidefelt **/ -##needs seq-support +##needs ..Shapes..Data / seq-support + +##lookin ..Shapes +##lookin ..Shapes..Data +##lookin ..Shapes..Geometry +##lookin ..Shapes..Layout +##lookin ..Shapes..Graphics /** Graph layout function for nodes on a circle. ** (Ignoring any previous content of node values.) @@ -39,7 +45,7 @@ groupMixedEdges: e2: e.target.index f1: f.source.index f2: f.target.index - [min e1 e2] = [min f1 f2] and [max e1 e2] = [max f1 f2] + [Numeric..Math..min e1 e2] = [Numeric..Math..min f1 f2] and [Numeric..Math..max e1 e2] = [Numeric..Math..max f1 f2] } /** Sort a group of edges such that parallel edges are adjacent in the sequence. @@ -53,7 +59,7 @@ groupMixedEdges: \ edges → { - sortKeys: [fmap ( \ e → [vector [min e.source.index e.target.index] [max e.source.index e.target.index]]) edges] + sortKeys: [fmap ( \ e → [vector [Numeric..Math..min e.source.index e.target.index] [Numeric..Math..max e.source.index e.target.index]]) edges] edgesSorted: [lexiographicSort sortKeys edges] [fmap sortEdgeGroup [equivalent_runs sameIncidentVertices edgesSorted]] } @@ -63,13 +69,13 @@ groupMixedEdges: **/ renderMixedGraph: \ g → { - nodeRadius: 0.75*@text_size + nodeRadius: 0.75*Text..@size /** A circle at each node **/ nodeCircles: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] stroke[][circle nodeRadius]]) null] /** the node keys **/ - nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (newText << (newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) null] + nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (Text..newText << (String..newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) null] /** Stroke the edges **/ edgePath: \ e angleOffset → @@ -89,7 +95,7 @@ renderMixedGraph: \ g → drawEdgeGroup: \ edges → { n: edges.size - angleMax: [arctan 0.577350269 * (n - '1)] / 3 + angleMax: [Numeric..Math..arctan 0.577350269 * (n - '1)] / 3 [if n = '1 { e: [edges '0] @@ -135,4 +141,4 @@ g: [graph directed:true undirected:true /** Apply layout and rendering functions. **/ -@text_size:9bp & @width:0.3bp | [renderMixedGraph [circleGraphLayout g]] +Text..@size:9bp & Traits..@width:0.3bp | [renderMixedGraph [circleGraphLayout g]] diff --git a/examples/doc/graphs-multigraph.shape b/examples/doc/graphs-multigraph.shape index c2824f7b..3cbf3784 100644 --- a/examples/doc/graphs-multigraph.shape +++ b/examples/doc/graphs-multigraph.shape @@ -16,7 +16,13 @@ ** Copyright 2014 Henrik Tidefelt **/ -##needs seq-support +##needs ..Shapes..Data / seq-support + +##lookin ..Shapes +##lookin ..Shapes..Data +##lookin ..Shapes..Geometry +##lookin ..Shapes..Layout +##lookin ..Shapes..Graphics /** Graph layout function for nodes on a circle. ** (Ignoring any previous content of node values.) @@ -32,14 +38,14 @@ circleGraphLayout: \ g radius:3cm → renderMultiGraph: \ g → { /** Rendering parameters **/ - nodeRadius: 0.75 * @text_size - multiplicityRadius: 0.7 * @text_size + nodeRadius: 0.75 * Text..@size + multiplicityRadius: 0.7 * Text..@size /** A circle at each node. **/ nodeCircles: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] stroke[][circle nodeRadius]]) null] /** Node keys. **/ - nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (newText << (newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) null] + nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (Text..newText << (String..newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) null] /** Draw each multiedge as a straigt line between the nodes. **/ edgePath: \ me → @@ -55,14 +61,14 @@ renderMultiGraph: \ g → /** A label showing the multiplicity of a multiedge, positioned inside an imaginary circle of radius multiplicityRadius. **/ multiplicityLabel: \ count → - (newText << (newString << [sprintf `(%d)´ count]) ) >> center_x >> [shift (0,~0.5 * multiplicityRadius)] + (Text..newText << (String..newString << [String..sprintf `(%d)´ count]) ) >> center_x >> [shift (0,~0.5 * multiplicityRadius)] /** Stroke an edge path and add a multiplicity label to the side of the stroke. **/ drawMultiEdge: \ me → { p: [edgePath me] - sl: [p [abs p]/2] - (@width: 3 * @width | [stroke p head:[if me.directed? edgeArrow NO_ARROW]]) + sl: [p [Numeric..Math..abs p]/2] + (Traits..@width: 3 * Traits..@width | [stroke p head:[if me.directed? edgeArrow NO_ARROW]]) & [[shift sl.p + sl.N * multiplicityRadius] [multiplicityLabel me.count]] } @@ -88,4 +94,4 @@ g: [graph undirected:true parallel:true /** Apply layout and rendering functions. **/ -@text_size:9bp & @width:0.3bp | [renderMultiGraph [circleGraphLayout g]] +Text..@size:9bp & Traits..@width:0.3bp | [renderMultiGraph [circleGraphLayout g]] diff --git a/examples/doc/remainders.shape b/examples/doc/remainders.shape index 55b05e24..394a6928 100644 --- a/examples/doc/remainders.shape +++ b/examples/doc/remainders.shape @@ -150,7 +150,7 @@ remainderPlot: \ fun den → { •plot << [[shift (0,viewYMax)] [Layout..shiftoff_wlm (Text..newText << (String..newString << [Debug..sourceof fun] << ` ´ << den*1.0)) Layout..to_top]] } - plot: •plot; + plot: freeze •plot [Layout..enlarge_bleedbox plot (2mm,2mm)] } diff --git a/examples/doc/tutorial-view.shape b/examples/doc/tutorial-view.shape index 0c8643db..302a0344 100644 --- a/examples/doc/tutorial-view.shape +++ b/examples/doc/tutorial-view.shape @@ -69,7 +69,7 @@ foldtriplesl: [if [Data..nil? lst] lst [if [Data..nil? lst.cdr] - nil + Data..nil [helper op zero lst.car lst.cdr.car lst.cdr.cdr]]] } diff --git a/examples/features/folds.blank b/examples/features/folds.blank index 4483fdce..0c0c360a 100644 --- a/examples/features/folds.blank +++ b/examples/features/folds.blank @@ -19,6 +19,7 @@ ##needs ..Shapes..Data / seq-support ##lookin ..Shapes +##lookin ..Shapes..Data lst: [Data..range begin:'4 end:'10] @@ -31,7 +32,7 @@ IO..•stdout << `Length: ´ << [lst.foldl (\ p e → '1+p) '0] << "{n} /** This is to show the order in which the state is modified when folding with state from left and right. **/ [lst.foldsl \ p e •dst → { •dst << e p } void IO..•stdout ] -[lst.foldsr \ p e •dst → { •dst << e p } void IO..•stdout ] +[lst.foldsr \ e p •dst → { •dst << e p } void IO..•stdout ] IO..•stdout << "{n} /** A classic example -- the sequence of Fibonacci numbers. diff --git a/examples/features/graphs.shape b/examples/features/graphs.shape index c64d131c..604f5618 100644 --- a/examples/features/graphs.shape +++ b/examples/features/graphs.shape @@ -16,7 +16,12 @@ ** Copyright 2013, 2014 Henrik Tidefelt **/ -##needs seq-support +##needs ..Shapes..Data / seq-support + +##lookin ..Shapes +##lookin ..Shapes..Data +##lookin ..Shapes..Geometry +##lookin ..Shapes..Layout /** Define two graphs to use in examples. **/ @@ -47,11 +52,11 @@ seq_sep_string: \ seq → [seq_string [separate ` ´ seq]] /** Examples of the most elementary operations on graphs: **/ -•stdout << `Graph domain has restriction to undirected graphs: ´ << g.undirected? << "{n} -•stdout << `Number of nodes in g: ´ << g.node_count << "{n} -•stdout << `Nodes in g: ´ << [seq_string [separate ` ´ g.nodes]] << "{n} -•stdout << `Number of edges in g: ´ << g.edge_count << "{n} -•stdout << `Edges in g: ´ << seq_sep_string [] g.edges << "{n} /** edges = u_edges + d_edges **/ +IO..•stdout << `Graph domain has restriction to undirected graphs: ´ << g.undirected? << "{n} +IO..•stdout << `Number of nodes in g: ´ << g.node_count << "{n} +IO..•stdout << `Nodes in g: ´ << [seq_string [separate ` ´ g.nodes]] << "{n} +IO..•stdout << `Number of edges in g: ´ << g.edge_count << "{n} +IO..•stdout << `Edges in g: ´ << seq_sep_string [] g.edges << "{n} /** edges = u_edges + d_edges **/ /** Examples of finding and working with nodes and edges. **/ @@ -59,20 +64,20 @@ node_ga: [g.find_node 'a] node_gb: [g.find_node 'b] node_gc: [g.find_node 'c] node_ha: [h.find_node 'a] -•stdout << `Key of node_ga: ´ << node_ga.key << "{n} -•stdout << `Key of node_ha: ´ << node_ha.key << "{n} -•stdout << `Degree of node_ga: ´ << node_ga.degree << "{n} /** degree = in_degree + out_degree + und_degree **/ -•stdout << `Degree of node_ha: ´ << node_ha.degree << "{n} -•stdout << `node_ga belongs to g: ´ << [g.node? node_ga] << "{n} -•stdout << `node_ga belongs to h: ´ << [h.node? node_ga] << "{n} -•stdout << `'q is a node key in g: ´ << [g.key? 'q] << "{n} -•stdout << `Edges incident to node_ga: ´ << seq_sep_string [] [node_ga.edges] << "{n} /** Note that node_ga.edges is a method **/ -•stdout << `Get all edges in g from 'b to 'c: ´ << seq_sep_string [] [g.find_d_edges 'b 'c] << "{n} -•stdout << `g has an edge from 'b to 'c: ´ << not [nil? [g.find_d_edges 'b 'c]] << "{n} /** will warn if domain does not allow directed edges **/ -•stdout << `h has an edge between 'b and 'c: ´ << not [nil? [h.find_u_edges 'b 'c]] << ` alternatively: ´<< not [nil? [h.find_u_edges 'c 'b]] << "{n} -•stdout << `Get _the_ edge from 'b to 'c: ´ << [h.the_u_edge 'b 'c] << "{n} /** error if there is no exactly one edge **/ -•stdout << `Verify that the result is an edge in h: ´ << [h.edge? [h.the_u_edge 'b 'c]] << "{n} /** edge? works both d_edge and u_edge **/ -•stdout << `Find edges using nodes: ´ << seq_sep_string [] [g.find_d_edges node_ga node_gb] << "{n} /** More efficient than using keys. **/ +IO..•stdout << `Key of node_ga: ´ << node_ga.key << "{n} +IO..•stdout << `Key of node_ha: ´ << node_ha.key << "{n} +IO..•stdout << `Degree of node_ga: ´ << node_ga.degree << "{n} /** degree = in_degree + out_degree + und_degree **/ +IO..•stdout << `Degree of node_ha: ´ << node_ha.degree << "{n} +IO..•stdout << `node_ga belongs to g: ´ << [g.node? node_ga] << "{n} +IO..•stdout << `node_ga belongs to h: ´ << [h.node? node_ga] << "{n} +IO..•stdout << `'q is a node key in g: ´ << [g.key? 'q] << "{n} +IO..•stdout << `Edges incident to node_ga: ´ << seq_sep_string [] [node_ga.edges] << "{n} /** Note that node_ga.edges is a method **/ +IO..•stdout << `Get all edges in g from 'b to 'c: ´ << seq_sep_string [] [g.find_d_edges 'b 'c] << "{n} +IO..•stdout << `g has an edge from 'b to 'c: ´ << not [nil? [g.find_d_edges 'b 'c]] << "{n} /** will warn if domain does not allow directed edges **/ +IO..•stdout << `h has an edge between 'b and 'c: ´ << not [nil? [h.find_u_edges 'b 'c]] << ` alternatively: ´<< not [nil? [h.find_u_edges 'c 'b]] << "{n} +IO..•stdout << `Get _the_ edge from 'b to 'c: ´ << [h.the_u_edge 'b 'c] << "{n} /** error if there is no exactly one edge **/ +IO..•stdout << `Verify that the result is an edge in h: ´ << [h.edge? [h.the_u_edge 'b 'c]] << "{n} /** edge? works both d_edge and u_edge **/ +IO..•stdout << `Find edges using nodes: ´ << seq_sep_string [] [g.find_d_edges node_ga node_gb] << "{n} /** More efficient than using keys. **/ /** Edges can be traced and backtraced to find the node on the other side. ** A directed edge can only be traced in its forward direction, and backtraced in its reverse direction, @@ -81,22 +86,22 @@ node_ha: [h.find_node 'a] eg: g.edges.car /** Just take any edge in a directed graph. **/ egs: eg.source egt: eg.target -•stdout << `Node reached by tracing ´ << eg << ` from ´ << egs << `: ´ << [egs.trace eg] << "{n} -•stdout << `Node reached by backtracing ´ << eg << ` from ´ << egt << `: ´ << [egt.backtrace eg] << "{n} +IO..•stdout << `Node reached by tracing ´ << eg << ` from ´ << egs << `: ´ << [egs.trace eg] << "{n} +IO..•stdout << `Node reached by backtracing ´ << eg << ` from ´ << egt << `: ´ << [egt.backtrace eg] << "{n} eh: h.edges.car /** Just take any edge in an undirected graph. **/ ehs: eh.source eht: eh.target -•stdout << `Node reached by tracing ´ << eh << ` from ´ << ehs << `: ´ << [ehs.trace eh] << "{n} -•stdout << `Node reached by tracing ´ << eh << ` from ´ << eht << `: ´ << [eht.trace eh] << "{n} -•stdout << `Node reached by backtracing ´ << eh << ` from ´ << ehs << `: ´ << [ehs.backtrace eh] << "{n} -•stdout << `Node reached by backtracing ´ << eh << ` from ´ << eht << `: ´ << [eht.backtrace eh] << "{n} +IO..•stdout << `Node reached by tracing ´ << eh << ` from ´ << ehs << `: ´ << [ehs.trace eh] << "{n} +IO..•stdout << `Node reached by tracing ´ << eh << ` from ´ << eht << `: ´ << [eht.trace eh] << "{n} +IO..•stdout << `Node reached by backtracing ´ << eh << ` from ´ << ehs << `: ´ << [ehs.backtrace eh] << "{n} +IO..•stdout << `Node reached by backtracing ´ << eh << ` from ´ << eht << `: ´ << [eht.backtrace eh] << "{n} /** Basic operations on node and edge indices. **/ -•stdout << `Index of node_gb: ´ << node_gb.index << "{n} -•stdout << `Retrieve node_gb via its index: ´ << [g.index_node node_gb.index] << "{n} -•stdout << `Index of eg: ´ << eg.index << "{n} -•stdout << `Retrieve eg via its index: ´ << [g.index_edge eg.index] << "{n} +IO..•stdout << `Index of node_gb: ´ << node_gb.index << "{n} +IO..•stdout << `Retrieve node_gb via its index: ´ << [g.index_node node_gb.index] << "{n} +IO..•stdout << `Index of eg: ´ << eg.index << "{n} +IO..•stdout << `Retrieve eg via its index: ´ << [g.index_edge eg.index] << "{n} /** Every node and edge can have a value. ** Values can be of arbitrary type, but it makes sense to keep all node values of the same type, and @@ -108,25 +113,25 @@ gv: [graph directed:true ] /** The value is accessed by a field named value. **/ -•stdout << `Value of a node: ´ << [gv.find_node 'a].value << "{n} -•stdout << `Value of an edge: ´ << [gv.the_d_edge 'a 'd].value << "{n} +IO..•stdout << `Value of a node: ´ << [gv.find_node 'a].value << "{n} +IO..•stdout << `Value of an edge: ´ << [gv.the_d_edge 'a 'd].value << "{n} /** Replacing all edge or node values are fast operations (typically much faster than constructing ** the list of new values). **/ -gv2: [gv.with_node_values [fmap \ n → (newString << `(´ << n.value << `)´) gv.nodes]] -•stdout << `Value of a node in gv2: ´ << [gv2.find_node 'c].value << "{n} +gv2: [gv.with_node_values [fmap \ n → (String..newString << `(´ << n.value << `)´) gv.nodes]] +IO..•stdout << `Value of a node in gv2: ´ << [gv2.find_node 'c].value << "{n} /** Nodes and edges may be removed from a graph by constructing induced or spanning subgraphs. ** The induced subgraph only keeps some (or sometimes all, but in a certain order) of the original nodes, ** while the spanning subgraph only some of the edges (but all nodes). **/ gInd: [g.induced_subgraph [list node_gc node_ga node_gb]] -•stdout << `Nodes in gInd: ´ << [seq_string [separate ` ´ gInd.nodes]] << "{n} -•stdout << `Edges in gInd: ´ << seq_sep_string [] gInd.edges << "{n} -gSpan: [g.spanning_subgraph [ffilter (\ e → ([mod e.index '2] = '0)) g.edges]] -•stdout << `Nodes in gSpan: ´ << [seq_string [separate ` ´ gSpan.nodes]] << "{n} -•stdout << `Edges in gSpan: ´ << seq_sep_string [] gSpan.edges << "{n} +IO..•stdout << `Nodes in gInd: ´ << [seq_string [separate ` ´ gInd.nodes]] << "{n} +IO..•stdout << `Edges in gInd: ´ << seq_sep_string [] gInd.edges << "{n} +gSpan: [g.spanning_subgraph [ffilter (\ e → ([Numeric..Math..mod e.index '2] = '0)) g.edges]] +IO..•stdout << `Nodes in gSpan: ´ << [seq_string [separate ` ´ gSpan.nodes]] << "{n} +IO..•stdout << `Edges in gSpan: ´ << seq_sep_string [] gSpan.edges << "{n} /** Additions to a graph can be expressed using a #Graph state. ** The state is always initialize with the contents of an existing graph. In particular, the graph domain @@ -140,7 +145,7 @@ gs: •dst.[edge 'a 'f] freeze •dst } -•stdout << `Edges in gs: ´ << seq_sep_string [] gs.edges << "{n} +IO..•stdout << `Edges in gs: ´ << seq_sep_string [] gs.edges << "{n} /** A graph may have parallel edges. To make it possible to distinguish between ** several edges sharing the same source and target, each edge may carry a label. @@ -154,12 +159,12 @@ mg: [graph undirected:true parallel:true (> 'c 'b `chord´ label:'even <) (> 'c 'b `that´ label:'odd <) ] ] -•stdout << `Edge values in mg: ´ << seq_sep_string [] [fmap (\ e → e.value) mg.edges] << "{n} -•stdout << `"Odd" edge values in mg: ´ << seq_sep_string [] [fmap (\ e → e.value) [mg.find_u_edges label:'odd]] << "{n} -•stdout << `The value on the edge between 'b and 'a labeled 'even: ´ << [mg.the_u_edge 'b 'a label:'odd].value << "{n} +IO..•stdout << `Edge values in mg: ´ << seq_sep_string [] [fmap (\ e → e.value) mg.edges] << "{n} +IO..•stdout << `"Odd" edge values in mg: ´ << seq_sep_string [] [fmap (\ e → e.value) [mg.find_u_edges label:'odd]] << "{n} +IO..•stdout << `The value on the edge between 'b and 'a labeled 'even: ´ << [mg.the_u_edge 'b 'a label:'odd].value << "{n} mebc: [mg.the_u_multiedge 'b 'c] -•stdout << `Multiedge between 'b and 'c: ´ << mebc << "{n} -•stdout << `Edge values in the multiedge: ´ << seq_sep_string [] [fmap (\ e → e.value) mebc.edges] << "{n} +IO..•stdout << `Multiedge between 'b and 'c: ´ << mebc << "{n} +IO..•stdout << `Edge values in the multiedge: ´ << seq_sep_string [] [fmap (\ e → e.value) mebc.edges] << "{n} /** In a partitioned graph, the nodes incident to an edge may not belong to ** the same partition. Each partition is identified by a key, and the keys @@ -172,8 +177,8 @@ bpg: [graph undirected:true partitions:[list 'left 'right] ] edges: [list (> 'a 'A <) (> 'a 'C <) (> 'b 'A <) (> 'c 'C <)] ] -•stdout << `Is bpg partitioned: ´ << bpg.partitioned? << "{n} -•stdout << `Nodes in right partition: ´ << seq_sep_string [] [bpg.partition 'right] << "{n} +IO..•stdout << `Is bpg partitioned: ´ << bpg.partitioned? << "{n} +IO..•stdout << `Nodes in right partition: ´ << seq_sep_string [] [bpg.partition 'right] << "{n} /** Finally, a very basic example of how graphs may be rendered. ** @@ -201,13 +206,13 @@ circleGraphLayout: \ g radius:3cm → **/ renderGraph: \ g → { - nodeRadius: 0.75*@text_size + nodeRadius: 0.75*Text..@size /** A circle at each node **/ - nodeCircles: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] stroke[][circle nodeRadius]]) null] + nodeCircles: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] Graphics..stroke[][circle nodeRadius]]) Graphics..null] /** the node keys **/ - nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (newText << (newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) null] + nodeKeys: [g.nodes.foldl \ s n → (s & [[shift n.value.coords] (Text..newText << (String..newString << n.key) ) >> center_x >> [shift (0,~0.5*nodeRadius)]]) Graphics..null] /** Stroke the edges **/ edgePath: \ e → @@ -217,11 +222,11 @@ renderGraph: \ g → tmp: source--target (source + nodeRadius * tmp.begin.T)--(target + nodeRadius * tmp.end.rT) } - edgeArrow: [ShapesArrow width:4bp ...] - edgeStrokes: [g.edges.foldl \ s e → (s & [stroke [edgePath e] head:[if e.directed? edgeArrow NO_ARROW]]) null] + edgeArrow: [Graphics..ShapesArrow width:4bp ...] + edgeStrokes: [g.edges.foldl \ s e → (s & [Graphics..stroke [edgePath e] head:[if e.directed? edgeArrow Graphics..NO_ARROW]]) Graphics..null] nodeCircles & nodeKeys & edgeStrokes } /** Apply layout and rendering functions to one of the graphs. **/ -@text_size:9bp & @width:0.3bp | [renderGraph [circleGraphLayout g]] +Text..@size:9bp & Traits..@width:0.3bp | [renderGraph [circleGraphLayout g]] diff --git a/examples/features/hulls.shape b/examples/features/hulls.shape index f27b38b4..c4ec47c4 100644 --- a/examples/features/hulls.shape +++ b/examples/features/hulls.shape @@ -21,6 +21,8 @@ ##lookin ..Shapes..Numeric..Random randPath: \ •state n → + @defaultunit: 1%C + | [[Data..range '1 n].foldsl •state \ •st pile e → pile--( ^ )<(1cm*[ball2D •st])>( 2mm * (1+[ball1D•st]) ^ 180°*[ball1D•st] ) diff --git a/examples/features/intersections.shape b/examples/features/intersections.shape index 68c822ed..158d5ad8 100644 --- a/examples/features/intersections.shape +++ b/examples/features/intersections.shape @@ -59,6 +59,8 @@ IO..•page << [shift (0cm,4cm)] [] [Graphics..TeX `\parbox{4cm}{Lines start at |** ) randPath: \ n •state → + @defaultunit:1%C + | [scale 5] [] [[Data..range '1 n].foldsl \ pile e •st → pile--( ^ )<(1cm*[ball2D •st])>( 2mm * (1+[ball1D •st]) ^ 180°*[ball1D •st] ) diff --git a/examples/features/lists.shape b/examples/features/lists.shape index 114bb4d2..f4ed3805 100644 --- a/examples/features/lists.shape +++ b/examples/features/lists.shape @@ -16,6 +16,9 @@ ** Copyright 2013 Henrik Tidefelt **/ +##lookin ..Shapes +##lookin ..Shapes..Data + lst1: [list 1 2 3] lst2: [cons 1 [cons 2 [cons 3 nil]]] lst3: 1 ; 2 ; 3 ; nil @@ -24,11 +27,11 @@ lst5: [cons 1 [range 2 3]] lst6: 1 ; [cons 2 [list 3]] /** All lists have the same fields and methods. **/ -•stdout << lst1.car << ` ´ << lst2.car << ` ´ << lst3.car << ` ´ << lst4.car << ` ´ << lst5.car << ` ´ << lst6.car << "{n} -•stdout << lst1.cdr << ` ´ << lst2.cdr << ` ´ << lst3.cdr << ` ´ << lst4.cdr << ` ´ << lst5.cdr << ` ´ << lst6.cdr << "{n} -opl: \ p e → p + (newString << e) -•stdout << [lst1.foldl opl `0´] << ` ´ << [lst2.foldl opl `0´] << ` ´ << [lst3.foldl opl `0´] << ` ´ << [lst4.foldl opl `0´] << ` ´ << [lst5.foldl opl `0´] << ` ´ << [lst6.foldl opl `0´] << "{n} -opr: \ e p → (newString << e) + p -•stdout << [lst1.foldr opr `4´] << ` ´ << [lst2.foldr opr `4´] << ` ´ << [lst3.foldr opr `4´] << ` ´ << [lst4.foldr opr `4´] << ` ´ << [lst5.foldr opr `4´] << ` ´ << [lst6.foldr opr `4´] << "{n} +IO..•stdout << lst1.car << ` ´ << lst2.car << ` ´ << lst3.car << ` ´ << lst4.car << ` ´ << lst5.car << ` ´ << lst6.car << "{n} +IO..•stdout << lst1.cdr << ` ´ << lst2.cdr << ` ´ << lst3.cdr << ` ´ << lst4.cdr << ` ´ << lst5.cdr << ` ´ << lst6.cdr << "{n} +opl: \ p e → p + (String..newString << e) +IO..•stdout << [lst1.foldl opl `0´] << ` ´ << [lst2.foldl opl `0´] << ` ´ << [lst3.foldl opl `0´] << ` ´ << [lst4.foldl opl `0´] << ` ´ << [lst5.foldl opl `0´] << ` ´ << [lst6.foldl opl `0´] << "{n} +opr: \ e p → (String..newString << e) + p +IO..•stdout << [lst1.foldr opr `4´] << ` ´ << [lst2.foldr opr `4´] << ` ´ << [lst3.foldr opr `4´] << ` ´ << [lst4.foldr opr `4´] << ` ´ << [lst5.foldr opr `4´] << ` ´ << [lst6.foldr opr `4´] << "{n} -@spot +Graphics..@spot diff --git a/examples/misc/self.shape b/examples/misc/self.shape index e2880e00..a16889ff 100644 --- a/examples/misc/self.shape +++ b/examples/misc/self.shape @@ -31,6 +31,6 @@ makeObj: \ z → } obj: [makeObj 3] -•stdout << [obj.g 2] << "{n} +Shapes..IO..•stdout << [obj.g 2] << "{n} -@spot +Shapes..Graphics..@spot diff --git a/resources/extensions/Shapes/Data/seq-support.shext b/resources/extensions/Shapes/Data/seq-support.shext index c3a224a5..a886cd2d 100644 --- a/resources/extensions/Shapes/Data/seq-support.shext +++ b/resources/extensions/Shapes/Data/seq-support.shext @@ -166,7 +166,7 @@ equivalent_runs: **/ seq_string: \ seq → { - •dst: newString + •dst: ..Shapes..String..newString [insert seq •dst] freeze •dst } diff --git a/test/text/sort.shape b/test/text/sort.shape index 20c7dc3c..2cca39a7 100644 --- a/test/text/sort.shape +++ b/test/text/sort.shape @@ -16,8 +16,10 @@ ** Copyright 2014 Henrik Tidefelt **/ -##needs seq-support +##needs ..Shapes..Data / seq-support +##lookin ..Shapes +##lookin ..Shapes..Data /*********************************************************************************** ** Elementary tests on integer ranges. @@ -27,14 +29,14 @@ **/ incSeq: [range '0 '24] decSeq: [range '24 '0 step:'~1] -•stdout << [seq_string [separate ` ´ [sort incSeq (<)]]] << "{n} -•stdout << [seq_string [separate ` ´ [sort decSeq (<)]]] << "{n} +IO..•stdout << [seq_string [separate ` ´ [sort incSeq (<)]]] << "{n} +IO..•stdout << [seq_string [separate ` ´ [sort decSeq (<)]]] << "{n} /** Check the stability property of the sort. **/ lessFive: (\ x y → (x / '5) < (y / '5)) -•stdout << [seq_string [separate ` ´ [sort incSeq lessFive]]] << "{n} -•stdout << [seq_string [separate ` ´ [sort decSeq lessFive]]] << "{n} +IO..•stdout << [seq_string [separate ` ´ [sort incSeq lessFive]]] << "{n} +IO..•stdout << [seq_string [separate ` ´ [sort decSeq lessFive]]] << "{n} /*********************************************************************************** @@ -43,7 +45,7 @@ lessFive: (\ x y → (x / '5) < (y / '5)) /** Text input form of a sequence. **/ -seqInputForm: \ seq → (newString << `[list ´ << [seq_string [separate ` ´ seq]] << `]´) +seqInputForm: \ seq → (String..newString << `[list ´ << [seq_string [separate ` ´ seq]] << `]´) /** Data to be sorted. **/ @@ -63,7 +65,7 @@ values: /** Precedence test for sequences, using the operator < to compare elements. **/ seqLess: \ seq1 seq2 → - [cond + [Control..cond [cons ([nil? seq1] and [nil? seq2]) false] [cons [nil? seq1] true] [cons [nil? seq2] false] @@ -71,7 +73,7 @@ seqLess: \ seq1 seq2 → { v1: seq1.car v2: seq2.car - [cond + [Control..cond [cons (v1 < v2) true] [cons (v1 > v2) false] [cons true [seqLess seq1.cdr seq2.cdr]] @@ -83,7 +85,7 @@ seqLess: \ seq1 seq2 → /** Sort values, and show. **/ valuesSorted: [sort values seqLess] -•stdout << [seq_string [separate "{n} [fmap seqInputForm valuesSorted]]] << "{n} +IO..•stdout << [seq_string [separate "{n} [fmap seqInputForm valuesSorted]]] << "{n} -@spot +Graphics..@spot -- 2.11.4.GIT