├── demo ├── favicon.ico ├── img │ ├── delphin.png │ └── content-save.png ├── demo.css ├── resources.js ├── index.html ├── demo.js └── elephant.json ├── .gitignore ├── LICENSE ├── README.md └── viz ├── delphin-viz.css ├── tree.js ├── dmrs.js └── mrs.js /demo/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/delph-in/delphin-viz/HEAD/demo/favicon.ico -------------------------------------------------------------------------------- /demo/img/delphin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/delph-in/delphin-viz/HEAD/demo/img/delphin.png -------------------------------------------------------------------------------- /demo/img/content-save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/delph-in/delphin-viz/HEAD/demo/img/content-save.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Ipython Notebook 62 | .ipynb_checkpoints 63 | 64 | # pyenv 65 | .python-version -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Ned Letcher 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # delphin-viz 2 | 3 | A library of JavaScript micro-tools for in-browser rendering of DELPH-IN data 4 | structure visualizations. Targets the developmental 5 | [DELPH-IN API]. 6 | 7 | ## Demo 8 | 9 | delphin-viz includes a demo interface which is modelled on the LOGON 10 | demo. A live version can be found [here][demo]. 11 | 12 | 13 | Dependencies (not including dependencies required for visualizations): 14 | * [jQuery] 15 | 16 | 17 | ## Visualizations 18 | 19 | All visualisations currently target SVG. The current aim is to gradually 20 | converge on using D3.js as the preferred rendering library and sole dependency, 21 | however this won't be a strict requirement. 22 | 23 | ### tree.js 24 | 25 | Renders DELPH-IN derivation trees. 26 | 27 | Dependencies: None 28 | 29 | ### mrs.js 30 | 31 | Renders vanilla MRS. 32 | 33 | Dependencies: 34 | * [svg.js] 35 | * [jQuery] 36 | * [jQuery UI] 37 | 38 | 39 | ### dmrs.js 40 | 41 | Renders Directed MRS. 42 | 43 | Dependencies: 44 | * [d3.js] 45 | 46 | 47 | [d3.js]: https://d3js.org/ 48 | [svg.js]: https://svgdotjs.github.io/ 49 | [jQuery]: https://jquery.com/ 50 | [jQuery UI]: https://jqueryui.com/ 51 | [demo]: http://delph-in.github.io/delphin-viz/demo/ 52 | [DELPH-IN API]: http://moin.delph-in.net/ErgApi 53 | -------------------------------------------------------------------------------- /demo/demo.css: -------------------------------------------------------------------------------- 1 | #container { 2 | max-width: 900px; 3 | margin: 2em auto; 4 | } 5 | 6 | #input-container { 7 | text-align: center; 8 | } 9 | 10 | #input-text { 11 | width: 400px; 12 | } 13 | 14 | .input-line { 15 | margin-top: 0.5em; 16 | } 17 | 18 | #text-input { 19 | font-size: 2em; 20 | } 21 | 22 | 23 | #results-info { 24 | text-align: center; 25 | } 26 | 27 | #results-container { 28 | display: table; 29 | width: 100%; 30 | margin-top: 2em; 31 | } 32 | 33 | .result { 34 | display: table-row; 35 | } 36 | 37 | .result-inner { 38 | display: table-cell; 39 | text-align: center; 40 | padding: 1em 0; 41 | } 42 | 43 | .result .num { 44 | font-size: 2em; 45 | display: inline-block; 46 | vertical-align: middle; 47 | text-align: center; 48 | padding-right: 1em; 49 | } 50 | 51 | .viz { 52 | display: inline-block; 53 | vertical-align: middle; 54 | position: relative; 55 | margin: 1em 2em; 56 | } 57 | 58 | 59 | /* Styling for the save icons -- needs to be moved into the visualisations. */ 60 | 61 | .hidden {display: none} 62 | 63 | .tools { 64 | position: absolute; 65 | right: 5px; 66 | top: -1.5em; 67 | } 68 | 69 | .save {display: inline-block} 70 | 71 | .save .icon { 72 | display: inline-block; 73 | vertical-align: middle; 74 | background: url('img/content-save.png') no-repeat; 75 | height: 24px; 76 | width: 24px; 77 | } 78 | 79 | .save div { 80 | display: inline-block; 81 | vertical-align: middle; 82 | font-family: sans-serif; 83 | font-size: 0.65em; 84 | font-weight: 600; 85 | } 86 | 87 | .save:hover { 88 | cursor: pointer; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /viz/delphin-viz.css: -------------------------------------------------------------------------------- 1 | .ui-tooltip { 2 | background: #444; 3 | border: 0px; 4 | border-radius: 8px; 5 | box-shadow: 0 0 5px rgba(0, 0, 0, .3); 6 | font: 12px sans-serif; 7 | padding: .3em; 8 | position: absolute; 9 | z-index: 9999; 10 | color: #FFF; 11 | opacity: 0.9; 12 | pointer-events: none; 13 | } 14 | 15 | .ui-helper-hidden-accessible { display: none} 16 | 17 | .highlighted {color: red} 18 | 19 | 20 | 21 | /* MRS specific */ 22 | 23 | 24 | .mrs { 25 | font-size: .9em; 26 | } 27 | 28 | .variable:hover { 29 | cursor: pointer; 30 | } 31 | 32 | .variable-feat-name { 33 | width: 60%; 34 | } 35 | 36 | 37 | 38 | /* DMRS specific */ 39 | 40 | .dmrs { 41 | display: inline-block; 42 | background-color: #FFF; 43 | border-radius: 10px; 44 | } 45 | 46 | .node { 47 | pointer-events: all; 48 | fill: #000; 49 | stroke: none; 50 | } 51 | 52 | .nodeText { 53 | stroke: none; 54 | font-family: sans-serif; 55 | font-size: 16px; 56 | text-anchor: middle; 57 | } 58 | 59 | .nodeText:hover { 60 | font-weight: bold; 61 | } 62 | 63 | .node.selected { 64 | font-weight: bold; 65 | } 66 | 67 | .nodeBox { 68 | stroke-width: 2px; 69 | fill: none; 70 | } 71 | 72 | .link { 73 | stroke: #000; 74 | fill: #000; 75 | stroke-opacity: .5; 76 | fill-opacity: .5; 77 | } 78 | 79 | .link path { 80 | fill: none; 81 | stroke-width: 2px; 82 | stroke-linejoin: round; 83 | marker-end: url(#arrowhead); 84 | } 85 | 86 | .link.eq path { 87 | fill: none; 88 | stroke-width: 2px; 89 | stroke-linejoin: round; 90 | stroke-dasharray: 5,5; 91 | } 92 | 93 | .link.top path { 94 | fill: #f00; 95 | stroke-width: 2px; 96 | stroke-linejoin: round; 97 | stroke-dasharray: 5,5; 98 | marker-end: url(#arrowhead); 99 | } 100 | 101 | .linkend { 102 | stroke-opacity: .5; 103 | fill-opacity: .5; 104 | } 105 | 106 | .link text.rargname { 107 | fill: #000; 108 | stroke: none; 109 | stroke-width: 1px; 110 | font-family: sans-serif; 111 | font-size: 10px; 112 | text-anchor: middle; 113 | } 114 | 115 | .link.top text.rargname { 116 | text-anchor: start; 117 | dominant-baseline: hanging; 118 | } 119 | 120 | .node.in { fill: red; } 121 | .node.out { fill: blue; } 122 | .node.labelset { stroke: gold; } 123 | .node.scope { stroke: violet; } 124 | .node.out.labelset { fill: green; stroke: gold;} 125 | .node.in.labelset { fill: darkorange; stroke: gold;} 126 | 127 | .link.in { fill: red; stroke: red; } 128 | .link.out { fill: blue; stroke: blue; } 129 | .link.labelset { fill: gold; stroke: gold; } 130 | .link.scope { fill: violet; stroke: violet; } 131 | .link.in.labelset { fill: darkorange; stroke: darkorange; } 132 | .link.out.labelset { fill: green; stroke: green; } 133 | 134 | /* thanks: http://bl.ocks.org/d3noob/a22c42db65eb00d4e369 */ 135 | .tooltip { 136 | position: absolute; 137 | text-align: center; 138 | padding: 2px; 139 | font: 12px sans-serif; 140 | color: #FFF; 141 | background: #444; 142 | border: 0px; 143 | border-radius: 8px; 144 | opacity: 0; 145 | pointer-events: none; 146 | box-shadow: 0 0 5px rgba(0, 0, 0, .3); 147 | } 148 | -------------------------------------------------------------------------------- /demo/resources.js: -------------------------------------------------------------------------------- 1 | // Capabilities of the two different server types that are currently able to 2 | // provide the DELPH-IN restful API. 3 | CAPABILITIES = { 4 | 'lkb' : { 5 | 'tree' : ['json'], 6 | 'mrs' : ['json', 'latex'], 7 | 'eds' : ['json', 'latex'], 8 | 'dmrs' : [] 9 | }, 10 | 'pydelphin' : { 11 | 'tree' : ['json'], 12 | 'mrs' : ['json'], 13 | 'eds' : [], 14 | 'dmrs' : ['json', 'latex'] 15 | } 16 | }; 17 | 18 | 19 | // Ordered list of grammar resource identifiers for presenting in the demo. 20 | // Should correspond to keys of RESOURCES object. 21 | var GRAMMARS = [ 22 | 'erg2018-uw', 23 | 'erg1214-uw', 24 | 'erg-uio', 25 | 'jacy-uw', 26 | 'indra-uw', 27 | 'zhong-uw', 28 | //'gg-um', 29 | //'hag-um' 30 | ]; 31 | 32 | 33 | var RESOURCES = { 34 | 'erg-uio': { 35 | grammar: 'ERG 1214', 36 | lang: 'eng', 37 | server: 'lkb', 38 | location: 'UiO', 39 | url: 'http://erg.delph-in.net/rest/0.9/parse', 40 | inputs: ['Abrams knew that it rained.'] 41 | }, 42 | 'erg1214-uw': { 43 | grammar: 'ERG 1214', 44 | lang: 'eng', 45 | server: 'pydelphin', 46 | location: 'UW', 47 | url: 'https://chimpanzee.ling.washington.edu/bottlenose/erg-1214/parse', 48 | inputs: ['Abrams knew that it rained.'] 49 | }, 50 | 'erg2018-uw': { 51 | grammar: 'ERG 2018', 52 | lang: 'eng', 53 | server: 'pydelphin', 54 | location: 'UW', 55 | url: 'https://chimpanzee.ling.washington.edu/bottlenose/erg-2018/parse', 56 | inputs: ['Abrams knew that it rained.'] 57 | }, 58 | 'jacy-uw': { 59 | grammar: 'Jacy', 60 | lang: 'jpn', 61 | server: 'pydelphin', 62 | location: 'UW', 63 | url: 'https://chimpanzee.ling.washington.edu/bottlenose/jacy/parse', 64 | inputs: ['太郎 が 雨 が 降っ た こと を 知っ て い た .'] 65 | }, 66 | 'indra-uw': { 67 | grammar: 'Indra', 68 | lang: 'ind', 69 | server: 'pydelphin', 70 | location: 'UW', 71 | url: 'https://chimpanzee.ling.washington.edu/bottlenose/indra/parse', 72 | inputs: ['Adi tahu bahwa hujan sudah turun.'] 73 | }, 74 | 'zhong-uw': { 75 | grammar: 'Zhong', 76 | lang: 'cmn', 77 | server: 'pydelphin', 78 | location: 'UW', 79 | url: 'https://chimpanzee.ling.washington.edu/bottlenose/zhong/parse', 80 | inputs: ['张三 知道 下 过 雨 。'] 81 | } 82 | // currently offline 83 | // 'gg-um': { 84 | // grammar: 'gg', 85 | // lang: 'deu', 86 | // server: 'pydelphin', 87 | // location: 'UM', 88 | // url: 'http://nedned.cis.unimelb.edu.au/bottlenose/gg/parse', 89 | // inputs: ['Abrams wusste, dass es regnete.'] 90 | // }, 91 | // 'hag-um': { 92 | // grammar: 'Hausa', 93 | // lang: 'hau', 94 | // server: 'pydelphin', 95 | // location: 'UM', 96 | // url: 'http://nedned.cis.unimelb.edu.au/bottlenose/hag/parse', 97 | // inputs: ['Állàh yà gáafàrtà máalàm'] 98 | // } 99 | }; 100 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Demo (delphin-viz) 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 |

A tool for visualising parse trees produced by DELPH-IN grammars. 26 | Targets the developmental API. 27 | The source code can be found on GitHub.

28 |
29 |
30 | 31 | 32 |
33 |

Example sentence: Abrams knew that it rained.

34 |
35 | Grammar: 36 | 38 | Results: 39 | 47 | Tree 48 | ; 49 | MRS 50 | ; 51 | DMRS 52 | ; 53 |
54 |
55 |
56 |
57 | 58 |
59 |
60 |
61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /viz/tree.js: -------------------------------------------------------------------------------- 1 | /* An SVG renderer for DELPH-IN derivation trees. Targets the ERG API that is 2 | * currently under development and is documented here: 3 | * http://moin.delph-in.net/ErgApi 4 | * 5 | * This code is adapted from code found in Woodley Packard's full forest treebanker, 6 | * which can be found here: http://sweaglesw.org/svn/treebank/trunk/ 7 | * 8 | * Usage: 9 | * drawTree(derivation, element) 10 | * 11 | * Where 'derivation' is a derivation object as found in the ERG API, and 12 | * 'element' as an element for the resultant SVG element to be appended to the 13 | * end of its content. 14 | */ 15 | 16 | 17 | // Horizontal distance between nodes 18 | var DAUGHTER_HSPACE = 20; 19 | 20 | // Vertical distance between nodes 21 | var DAUGHTER_VSPACE = 30; 22 | 23 | 24 | function drawTree(element, derivation) { 25 | // need to add the SVG to the DOM before rendering, otherwise the height of 26 | // SVG elements won't be available during rendering. 27 | var svg = svgelement('svg'); 28 | svg.setAttribute("xmlns", "http://www.w3.org/2000/svg"); 29 | svg.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); 30 | svg.setAttributeNS(null, "version", "1.1"); 31 | element.appendChild(svg); 32 | 33 | var g = render_tree(svg, derivation); 34 | svg.appendChild(g); 35 | 36 | // Set dimensions on the SVG element from its top level g element 37 | var bbox = g.getBBox(); 38 | svg.setAttributeNS(null, "height", bbox.height); 39 | svg.setAttributeNS(null, "width", bbox.width); 40 | 41 | return svg; 42 | } 43 | 44 | 45 | function render_tree(svg, tree) { 46 | var lexical; 47 | var daughters = []; 48 | var wtot = -DAUGHTER_HSPACE; 49 | var dtr_label_mean = 0; 50 | 51 | for(var x in tree.daughters) { 52 | wtot += DAUGHTER_HSPACE; 53 | daughters[x] = render_tree(svg, tree.daughters[x]); 54 | dtr_label_mean += wtot + daughters[x].labelcenter; 55 | wtot += daughters[x].mywidth; 56 | } 57 | 58 | var lexical; 59 | if(daughters.length) { 60 | dtr_label_mean /= daughters.length; 61 | } else { 62 | lexical = render_yield(svg, tree.form); 63 | wtot = lexical.mywidth; 64 | dtr_label_mean = wtot / 2; 65 | } 66 | 67 | var node_str; 68 | if (tree.hasOwnProperty("label")) 69 | node_str = tree.label; 70 | else 71 | node_str = tree.entity; 72 | 73 | var g = svgelement("g"); 74 | var n = text(svg, node_str); 75 | n.setAttributeNS(null, "title", tree.entity); 76 | 77 | // add a title element for node tooltips 78 | var title = svgelement('title'); 79 | title.innerHTML = tree.entity; 80 | n.appendChild(title); 81 | 82 | g.appendChild(n); 83 | 84 | var daughters_wtot = wtot; 85 | var nw = n.bbx.width; 86 | var nh = n.bbx.height; 87 | var labelcenter = dtr_label_mean; 88 | 89 | if(labelcenter - nw/2 < 0) 90 | labelcenter = nw/2; 91 | 92 | if(labelcenter + nw/2 > wtot) 93 | labelcenter = wtot - nw/2; 94 | 95 | if(nw > wtot) { 96 | wtot = nw; 97 | labelcenter = wtot / 2; 98 | } 99 | 100 | n.setAttributeNS(null, "x", labelcenter - nw / 2); 101 | n.setAttributeNS(null, "y", nh * 2/3); 102 | 103 | var dtr_x = wtot / 2 - daughters_wtot / 2; 104 | var ytrans = nh + DAUGHTER_VSPACE; 105 | 106 | if(lexical) { 107 | var tvalue = "translate(" + dtr_x + "," + ytrans + ")"; 108 | var yline = nh + DAUGHTER_VSPACE - 1; 109 | lexical.setAttributeNS(null, "transform", tvalue); 110 | lexical.setAttributeNS(null, "class", "leaf"); 111 | g.appendChild(line(labelcenter, nh, wtot/2, yline)); 112 | g.appendChild(lexical); 113 | } else { 114 | for(var i=0; i < daughters.length; i++) { 115 | var daughter = daughters[i]; 116 | var tvalue = "translate(" + dtr_x + "," + ytrans + ")"; 117 | var yline = nh + DAUGHTER_VSPACE - 1; 118 | daughter.setAttributeNS(null, "transform", tvalue); 119 | g.appendChild(line(labelcenter, nh, dtr_x + daughter.labelcenter, yline)); 120 | g.appendChild(daughter); 121 | dtr_x += daughter.mywidth + DAUGHTER_HSPACE; 122 | } 123 | } 124 | 125 | g.mywidth = wtot; 126 | g.labelcenter = labelcenter; 127 | g.labelheight = nh; 128 | return g; 129 | } 130 | 131 | 132 | function render_yield(svg, str) { 133 | var y = text(svg, str); 134 | y.setAttributeNS(null, "y", y.bbx.height * 2/3); 135 | var g = svgelement("g"); 136 | g.appendChild(y); 137 | g.mywidth = y.bbx.width; 138 | return g; 139 | } 140 | 141 | 142 | function svgelement(type) { 143 | return document.createElementNS("http://www.w3.org/2000/svg", type); 144 | } 145 | 146 | 147 | function line(x1, y1, x2, y2) { 148 | var l = svgelement("line"); 149 | l.setAttributeNS(null, "x1", x1); 150 | l.setAttributeNS(null, "x2", x2); 151 | l.setAttributeNS(null, "y1", y1); 152 | l.setAttributeNS(null, "y2", y2); 153 | l.setAttributeNS(null, "style", "stroke: black;"); 154 | return l; 155 | } 156 | 157 | 158 | function text(svg, str) { 159 | var text = svgelement("text"); 160 | text.appendChild(document.createTextNode(str)); 161 | svg.appendChild(text); 162 | var bbx = text.getBBox(); 163 | svg.removeChild(text); 164 | text.bbx = bbx; 165 | return text; 166 | } 167 | -------------------------------------------------------------------------------- /viz/dmrs.js: -------------------------------------------------------------------------------- 1 | 2 | function DMRS(parentElement, dmrs) { 3 | var dmrsData = JSON.parse(JSON.stringify(dmrs)); // make a copy 4 | 5 | var level_dy = 25, // vertical separation between edges 6 | edge_radius = 15, // rounded corner radius, 7 | edge_xoffset = 10, // outgoing edges aren't centered 8 | node_dx = 20; // horizontal separation between nodes 9 | 10 | var color = d3.scale.category20(); 11 | 12 | function prepareGraph() { 13 | var nodeIdx = {}, levelIdx = {}; 14 | dmrs.nodes.forEach(function(d, i) { 15 | nodeIdx[d.nodeid] = i; 16 | levelIdx[[i,i+1].join()] = {}; // eg levelIdx["1,2"] = {} 17 | }); 18 | dmrs.links.forEach(function(d) { 19 | d.target = nodeIdx[d.to]; 20 | // start of 0 is TOP link 21 | if (d.from == 0) { 22 | d.dir = 1; // always on top 23 | return; 24 | } 25 | // the rest only apply to non-TOP links 26 | d.source = nodeIdx[d.from]; 27 | d.distance = Math.abs(d.source - d.target); 28 | // Quantifiers and undirected EQ links below preds 29 | d.dir = (d.rargname == "" || d.post.toUpperCase() == "H") ? -1 : 1 30 | }); 31 | dmrs.maxTopLevel = 0; 32 | dmrs.maxBottomLevel = 0; 33 | for (dist=0; dist d.level) { 41 | dmrs.maxBottomLevel = d.level; 42 | } 43 | }); 44 | } 45 | dmrs.sticky = false; 46 | } 47 | 48 | function nextAvailableLevel(source, target, dir, lvlIdx) { 49 | var level, curLevel, success; 50 | if (source > target) 51 | return nextAvailableLevel(target, source, dir, lvlIdx); 52 | level = 0; 53 | curLevel = dir; 54 | while (level == 0) { 55 | success = true; 56 | for (var i = source; i < target; i++) { 57 | if (curLevel in lvlIdx[[i, i+1].join()]) { 58 | success = false; 59 | break; 60 | } 61 | } 62 | if (success) { 63 | level = curLevel; 64 | for (var i = source; i < target; i++) { 65 | lvlIdx[[i, i+1].join()][level] = true; 66 | } 67 | } else { 68 | curLevel += dir; 69 | } 70 | } 71 | return level; 72 | } 73 | 74 | function getPathSpec(link, dmrs) { 75 | var x1, x2, y1, y2; 76 | // get these first, they apply for all links 77 | x2 = dmrs.nodes[link.target].x; 78 | y1 = dmrs.nodes[link.target].bbox.height; 79 | if (link.from == 0) { 80 | y2 = y1 + (((link.dir == 1 ? dmrs.maxTopLevel : dmrs.maxBottomLevel) + 1) * level_dy); 81 | link.midpoint = {"x": x2 + 4, "y": y2}; 82 | return ["M", x2, y2, "L", x2, y1].join(' '); 83 | } 84 | // the following is only for non-TOP links 85 | x1 = dmrs.nodes[link.source].x; 86 | y2 = y1 + (Math.abs(link.level) * level_dy - 5); 87 | // side-effect! calculate this while we know it 88 | link.midpoint = {"x": (x1 + x2) / 2, 89 | "y": y2}; 90 | if (x1 < x2) { 91 | x1 += edge_xoffset; 92 | return ["M", x1, y1 - 5, 93 | "L", x1, (y2 - edge_radius), 94 | "Q", x1, y2, (x1 + edge_radius), y2, 95 | "L", (x2 - edge_radius), y2, 96 | "Q", x2, y2, x2, y2 - edge_radius, 97 | "L", x2, y1].join(' '); 98 | } else { 99 | x1 -= edge_xoffset; 100 | return ["M", x1, y1 - 5, 101 | "L", x1, (y2 - edge_radius), 102 | "Q", x1, y2, (x1 - edge_radius), y2, 103 | "L", (x2 + edge_radius), y2, 104 | "Q", x2, y2, x2, y2 - edge_radius, 105 | "L", x2, y1].join(' '); 106 | } 107 | } 108 | 109 | function updateHighlights(id) { 110 | clearHighlights(id); 111 | d3.select(id).selectAll(".node.selected").each(function(d){ 112 | var labelset = d3.set(), 113 | outs = d3.set(), 114 | ins = d3.set(), 115 | scopes = d3.set(); 116 | d3.select(id).selectAll(".link") 117 | .classed({ 118 | "out": function(_d) { 119 | if (_d.rargname && d.nodeid == _d.from) { 120 | outs.add(_d.to); 121 | return true; 122 | } 123 | return false; 124 | }, 125 | "in": function(_d) { 126 | if (_d.rargname && d.nodeid == _d.to) { 127 | ins.add(_d.from); 128 | return true; 129 | } 130 | return false; 131 | }, 132 | "labelset": function(_d) { 133 | if (_d.post == "EQ" && (_d.from == d.nodeid || _d.to == d.nodeid)) { 134 | labelset.add(_d.from); 135 | labelset.add(_d.to); 136 | return true; 137 | } 138 | return false 139 | }, 140 | "scope": function(_d) { 141 | if (_d.from == d.nodeid && (_d.post == "H" || _d.post == "HEQ")) { 142 | scopes.add(_d.to); 143 | return true; 144 | } else if (_d.to == d.nodeid && (_d.post == "H" || _d.post == "HEQ")) { 145 | return true; 146 | } 147 | return false; 148 | } 149 | }); 150 | var labelAdded = true; 151 | while (labelAdded) { 152 | labelAdded = false; 153 | d3.select(id).selectAll(".link").each(function(_d) { 154 | if (_d.post == "EQ") { 155 | if (labelset.has(_d.from) && !labelset.has(_d.to)) { 156 | labelset.add(_d.to); 157 | labelAdded = true; 158 | } else if (labelset.has(_d.to) && !labelset.has(_d.from)) { 159 | labelset.add(_d.from); 160 | labelAdded = true; 161 | } 162 | } 163 | }); 164 | } 165 | d3.select(id).selectAll(".node") 166 | .classed({ 167 | "out": function(_d) { return outs.has(_d.nodeid); }, 168 | "in": function(_d) { return ins.has(_d.nodeid); }, 169 | "labelset": function(_d) { return labelset.has(_d.nodeid); }, 170 | "scope": function(_d) { return scopes.has(_d.nodeid); } 171 | }); 172 | 173 | }); 174 | } 175 | 176 | function clearHighlights(id) { 177 | d3.select(id).selectAll(".node").classed( 178 | {"in": false, "out": false, "labelset": false, "scope": false} 179 | ); 180 | d3.select(id).selectAll(".link").classed( 181 | {"in": false, "out": false, "labelset": false, "scope": false} 182 | ); 183 | } 184 | 185 | function toggleSticky(id, node, d) { 186 | if (d.sticky) { 187 | d.sticky = false; 188 | d3.select(node).classed("selected", false); 189 | } else { 190 | d3.select(id).selectAll(".node.selected").each(function(_d) { 191 | _d.sticky = false; 192 | d3.select(this).classed("selected", false); 193 | }); 194 | d.sticky = true; 195 | d3.select(node).classed("selected", true); 196 | } 197 | return d.sticky; 198 | } 199 | 200 | 201 | function drawDmrs() { 202 | // d3.json(url, function(error, dmrs) { 203 | // calculate source and target for links 204 | prepareGraph(); 205 | 206 | var tip = d3.select("#tooltip") 207 | .style("opacity", 0); 208 | 209 | var id = parentElement; 210 | var svg = d3.select(parentElement) 211 | .classed("dmrs", true) 212 | .append('svg') 213 | .attr('xmlns', 'http://www.w3.org/2000/svg') 214 | .attr('version', '1.1') 215 | .attr('xmlns:link', 'http://www.w3.org/1999/xlink') 216 | .attr("height", ((dmrs.maxTopLevel - dmrs.maxBottomLevel + 3) * level_dy)); 217 | var g = svg.append("svg:g") 218 | .attr("transform", "translate(0," + ((dmrs.maxTopLevel + 2) * level_dy) + ")"); 219 | 220 | g.append("defs").append("marker") 221 | .attr("class", "linkend") 222 | .attr("id", "arrowhead") 223 | .attr("refX", 1) /*must be smarter way to calculate shift*/ 224 | .attr("refY", 2) 225 | .attr("markerWidth", 5) 226 | .attr("markerHeight", 4) 227 | .attr("orient", "auto") 228 | .append("path") 229 | .attr("d", "M0,0 L1,2 L0,4 L5,2 Z"); //this is actual shape for arrowhead 230 | 231 | var x_pos = 10; 232 | var nodes = g.selectAll(".node").order() 233 | .data(dmrs.nodes) 234 | .enter().append("svg:g") 235 | .attr("class", "node") 236 | .each(function(d) { 237 | var vps = []; 238 | for (var key in d.sortinfo) { 239 | vps.push("" + key + "=" + d.sortinfo[key] + ""); 240 | } 241 | d.tooltipText = "" + vps.join("") + "
"; 242 | }); 243 | nodes.append("svg:text") 244 | .attr("class", "nodeText") 245 | .text(function(d) { 246 | if (d.carg) { 247 | return d.predicate + "(" + d.carg + ")"; 248 | } else { 249 | return d.predicate; 250 | } 251 | }) 252 | .attr("x", function(d, i) { 253 | d.bbox = this.getBBox(); 254 | halfLen = d.bbox.width / 2; 255 | x = x_pos + halfLen; 256 | x_pos = x + halfLen + node_dx; 257 | d.x = x; 258 | return x; 259 | }) 260 | .attr("y", function(d) { return 0; }) 261 | .attr("dy", function(d) { return d.bbox.height/5; }); 262 | nodes.insert("svg:rect", "text") 263 | .attr("class", "nodeBox") 264 | .attr("x", function(d) { return d.x - (d.bbox.width / 2) - 2; }) 265 | .attr("y", function(d) { return - (d.bbox.height / 2) - 2; }) 266 | .attr("width", function(d) { return d.bbox.width + 4; }) 267 | .attr("height", function(d) { return d.bbox.height + 4; }) 268 | .attr("rx", 4) 269 | .attr("ry", 4); 270 | nodes.on("mouseover", function(d) { 271 | if (!dmrs.sticky) { d3.select(this).classed("selected", true) }; 272 | updateHighlights(id); 273 | tip.html(d.tooltipText) 274 | .style("opacity", 0.8); 275 | }) 276 | .on("mousemove", function(d) { 277 | tip.style("left", (d3.event.pageX - 10) + "px") 278 | .style("top", (d3.event.pageY + 15) + "px"); 279 | }) 280 | .on("mouseout", function(d) { 281 | if (!d.sticky) { d3.select(this).classed("selected", false); } 282 | updateHighlights(id); 283 | tip.style("opacity", 0); 284 | }) 285 | .on("click", function(d) { 286 | stickyState = toggleSticky(id, this, d); 287 | dmrs.sticky = stickyState; 288 | updateHighlights(id); 289 | }); 290 | 291 | // not working... 292 | svg.attr("width", d3.sum(nodes.data(), function(d) { return d.bbox.width + node_dx; })); 293 | 294 | var links = g.selectAll(".link").order() 295 | .data(dmrs.links) 296 | .enter().append("svg:g") 297 | .attr("class", function(d) { 298 | var classes = "link"; 299 | if (d.from == 0) { 300 | classes += " top"; 301 | } else if (d.rargname == "" && d.post == "EQ") { 302 | classes += " eq"; 303 | } else if (d.post == "H") { 304 | classes += " scopal"; 305 | } else { 306 | classes += " var"; 307 | } 308 | return classes; 309 | }); 310 | links.append("svg:path") 311 | .attr("d", function(d) { 312 | return getPathSpec(d, dmrs); 313 | }) 314 | .attr("transform", function(d) { 315 | return "scale(1," + (d.dir * -1) + ")"; 316 | }) 317 | .style("marker-end", function(d) { 318 | return (d.rargname == "" && d.post == "EQ") ? "none" : "url(#arrowhead)"; 319 | }); 320 | links.append("svg:text") 321 | .attr("class", "rargname") 322 | .attr("x", function(d) { return d.midpoint.x; }) 323 | .attr("y", function(d) { return d.midpoint.y * (-1 * d.dir) - 3; }) 324 | .text(function(d) { 325 | if (d.from == 0) { return "TOP"; } else { return d.rargname + "/" + d.post; } 326 | }); 327 | // }); 328 | return svg[0][0]; 329 | } 330 | 331 | var self = { 332 | parent: parentElement, 333 | data: dmrsData, 334 | element: drawDmrs() 335 | }; 336 | 337 | 338 | return self; 339 | } 340 | -------------------------------------------------------------------------------- /demo/demo.js: -------------------------------------------------------------------------------- 1 | function getCurrGramId() { 2 | return $('#input-grammar')[0].value; 3 | } 4 | 5 | 6 | function getCurrGrammar() { 7 | return RESOURCES[getCurrGramId()]; 8 | } 9 | 10 | 11 | // Using underscore.js/lodash.js Templates 12 | var Templates = {}; 13 | 14 | Templates.result = [ 15 | '
', 16 | '
', 17 | '
<%= resultNum %>
', 18 | '
', 19 | '
'].join("\n"); 20 | 21 | 22 | Templates.viz = [ 23 | '
', 24 | '', 29 | '
' 30 | ].join("\n"); 31 | 32 | 33 | Templates.successStatus = [ 34 | '

Showing <%= numResults %> of <%= readings %> analyses.

', 35 | '
<%= input %>
' 36 | ].join("\n"); 37 | 38 | 39 | // Precompile the templates 40 | for (var template in Templates) { 41 | if (Templates.hasOwnProperty(template)) { 42 | Templates[template] = _.template(Templates[template]); 43 | } 44 | } 45 | 46 | 47 | function setInlineStyles(svg, emptySvgDeclarationComputed) { 48 | // Applies computed CSS styles for an SVG to the element as inline 49 | // styles. This allows SVG elements to be saved as SVG and PNG images that 50 | // display as viewed in the browser. 51 | // This function taken from the svg-crowbar tool: 52 | // https://github.com/NYTimes/svg-crowbar/blob/gh-pages/svg-crowbar-2.js 53 | 54 | function explicitlySetStyle (element) { 55 | var cSSStyleDeclarationComputed = getComputedStyle(element); 56 | var i, len, key, value; 57 | var computedStyleStr = ""; 58 | for (i=0, len=cSSStyleDeclarationComputed.length; i')[0]; 121 | var ctx = canvas.getContext('2d'); 122 | ctx.canvas.height = bbox.height; 123 | ctx.canvas.width = bbox.width; 124 | ctx.fillStyle = 'white'; 125 | ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); 126 | 127 | // convert SVG to dataUrl 128 | var data = (new XMLSerializer()).serializeToString(svg); 129 | var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'}); 130 | var DOMURL = window.URL || window.webkitURL || window; 131 | var url = DOMURL.createObjectURL(svgBlob); 132 | 133 | var img = new Image(); 134 | img.onload = function () { 135 | ctx.drawImage(img, 0, 0); 136 | DOMURL.revokeObjectURL(url); 137 | 138 | var imgURI = canvas 139 | .toDataURL('image/png') 140 | .replace('image/png', 'image/octet-stream'); 141 | 142 | // on the image load, actually download it 143 | triggerDownload(imgURI, vizType+'.png'); 144 | }; 145 | img.src = url; 146 | }, 147 | saveVizLatex : function(vizType, resultNum) { 148 | var data = { 149 | input: $('#input-text').val(), 150 | results: $('#input-results').val() 151 | }; 152 | data[vizType] = 'latex'; 153 | 154 | $.ajax({ 155 | url: CURR_GRAMMAR.url, 156 | dataType: 'json', 157 | data: data, 158 | success: function(data){ 159 | var latex = data.results[resultNum][vizType]; 160 | var textBlob = new Blob([latex], {type: "text/plain;charset=utf-8"}); 161 | var DOMURL = window.URL || window.webkitURL || window; 162 | var url = DOMURL.createObjectURL(textBlob); 163 | triggerDownload(url, vizType+'.tex'); 164 | }, 165 | error: function(data){ 166 | // TODO: better error handling 167 | alert("Sorry, something went wrong saving LaTex."); 168 | } 169 | }); 170 | } 171 | }; 172 | 173 | var $inner = $result.find('.result-inner'); 174 | 175 | // Add data structures as per the available data 176 | if (self.data.derivation) { 177 | var $viz = $(Templates.viz({vizType:'tree'})).appendTo($inner); 178 | self.tree = {element: drawTree($viz[0], self.data.derivation)}; 179 | } 180 | 181 | if (self.data.mrs) { 182 | var $viz = $(Templates.viz({vizType:'mrs'})).appendTo($inner); 183 | self.mrs = MRS($viz[0], self.data.mrs); 184 | } 185 | 186 | if (self.data.dmrs) { 187 | var $viz = $(Templates.viz({vizType:'dmrs'})).appendTo($inner); 188 | self.dmrs = DMRS($viz[0], self.data.dmrs); 189 | } 190 | 191 | // remove any save links that are unsupported 192 | $inner.find('.viz').each(function (){ 193 | var vizType = this.dataset.viz; 194 | if (CAPABILITIES[CURR_GRAMMAR.server][vizType].indexOf('latex') == -1) { 195 | $(this).find('[data-img="latex"]').remove(); 196 | } 197 | }); 198 | 199 | //Add various event bindings to things in the visualisations 200 | $result.find('.viz').hover( 201 | function(event) { 202 | $(this).find('.tools').removeClass('hidden'); 203 | }, 204 | function(event) { 205 | $(this).find('.tools').addClass('hidden'); 206 | } 207 | ).each(function(index) { 208 | var vizType = this.dataset.viz; 209 | $(this).find('.save').click(function(event){ 210 | if (this.dataset.img == 'svg') { 211 | self.saveVizSvg(vizType); 212 | } else if (this.dataset.img == 'png') { 213 | self.saveVizPng(vizType); 214 | } else if (this.dataset.img == 'latex') { 215 | var resultNum = $(this).closest('.result').data('result'); 216 | self.saveVizLatex(vizType, resultNum); 217 | } 218 | }); 219 | }); 220 | 221 | // Return this object 222 | return self; 223 | } 224 | 225 | 226 | function triggerDownload (uri, filename) { 227 | var evt = new MouseEvent('click', { 228 | view: window, 229 | bubbles: false, 230 | cancelable: true 231 | }); 232 | 233 | var a = document.createElement('a'); 234 | a.setAttribute('download', filename); 235 | a.setAttribute('href', uri); 236 | a.setAttribute('target', '_blank'); 237 | a.dispatchEvent(evt); 238 | } 239 | 240 | 241 | function getQueryVariable(variable) { 242 | var query = window.location.search.substring(1); 243 | var vars = query.split("&"); 244 | 245 | for (var i=0;i', { 337 | value: gramId, 338 | text : grammar.grammar + ' (' + grammar.location + ')' 339 | })); 340 | } 341 | 342 | $('#input-submit').click(function(event) { 343 | var currGrammar = getCurrGrammar(); 344 | $.ajax({ 345 | url: currGrammar.url, 346 | dataType: 'json', 347 | data: { 348 | 'derivation': $('#input-tree').prop('checked') ? 'json' : "null", 349 | 'mrs': $('#input-mrs').prop('checked') ? 'json' : "null", 350 | 'dmrs': $('#input-dmrs').prop('checked') ? 'json' : "null", 351 | 'input': $('#input-text').val(), 352 | 'results': $('#input-results').val() 353 | }, 354 | dataFilter: function(data) { 355 | // Fix buggy JSON from LKB server 356 | return data.replace(/([^,]) "pedges"/, '$1, "pedges"'); 357 | }, 358 | success: function(data){ 359 | CURR_GRAMMAR = getCurrGrammar(); 360 | doResults(data); 361 | updateUrl(); 362 | }, 363 | error: function(data){ 364 | // TODO: improve error handling and reporting 365 | alert("Sorry, something went wrong."); 366 | } 367 | }); 368 | }); 369 | 370 | // Don't think this is still used 371 | $('#input-grammar').on('focusin', function(){ 372 | $(this).data('prev', $(this).val()); 373 | }); 374 | 375 | $('#input-grammar').change(function(event){ 376 | // Change the sample text 377 | $('#sample-text').text(getCurrGrammar().inputs[0]); 378 | }); 379 | 380 | if (loadUrlParams()) 381 | // Execute query stored in URL 382 | $('#input-submit').trigger('click'); 383 | else 384 | // No URL params, default to checking derivation tree 385 | $('#input-tree').prop('checked', true); 386 | 387 | if (getQueryVariable('dev') == 'true') { 388 | $.getJSON("elephant.json", function(data) { 389 | doResults(data); 390 | }); 391 | } 392 | 393 | // add empty svg element for use in saving SVGs as SVGs and PNGs 394 | var emptySvg = window.document.createElementNS("http://www.w3.org/2000/svg", 'svg'); 395 | window.document.body.appendChild(emptySvg); 396 | emptySvgDeclarationComputed = getComputedStyle(emptySvg); 397 | 398 | }); 399 | -------------------------------------------------------------------------------- /viz/mrs.js: -------------------------------------------------------------------------------- 1 | function MRS(parentElement, mrsData){ 2 | // Constant pixel sizes used 3 | const MAXWIDTH = 600; // width before a list of elements is wrapped 4 | const XGAP = 5; // horizontal gap between elements 5 | const YGAP = 5; // vertical gap between 1-line features 6 | const YGAPSTRUCT = 10; // vertical gap between full feature structures 7 | const BRACKETYPAD = 5; // distance bracket extents above/below box 8 | const BRACKETXWIDTH = 5; // width of right-angle corner thing 9 | const ANGLEHEIGHT = 50; // Height of angle brackets 10 | const ANGLEWIDTH = XGAP; // Width of angle brackets 11 | const FEATNAMEXGAP = 80; 12 | 13 | // Global offset for keeping track of where next thing needs to be drawn on 14 | // the Y axis. 15 | var CURRENTY = 0; 16 | 17 | function drawMrs() { 18 | var svg = SVG(parentElement); 19 | var mrs = svg.group(); 20 | var container = mrs.group(); 21 | 22 | CURRENTY = 0; 23 | drawFeatStructType(container, ''); 24 | drawFeatValPair(container, 'TOP', mrsData.top); 25 | drawFeatValPair(container, 'INDEX', mrsData.index); 26 | drawFeatValPair(container, 'RELS', mrsData.relations); 27 | drawFeatValPair(container, 'HCONS', mrsData.constraints); 28 | drawFeatValPair(container, 'ICONS', mrsData.constraints); 29 | drawSquareBrackets(mrs, XGAP); 30 | 31 | // transform the MRS to take into account the square brackets drawn at 32 | // negative coordinates 33 | mrs.transform({x:XGAP+10, y:BRACKETYPAD}); 34 | 35 | // update the dimensions of the final SVG to match those of the now 36 | // rendered MRS 37 | var finalBbox = mrs.tbox(); 38 | svg.size(finalBbox.width+10, finalBbox.height+5); 39 | return svg.node; 40 | } 41 | 42 | function drawFeatStructType(parent, name) { 43 | var text = parent.plain(name).y(CURRENTY).attr({'font-style':'italic'}); 44 | CURRENTY += text.tbox().height; 45 | return text; 46 | } 47 | 48 | function drawFeatValPair(parent, name, value) { 49 | var group = parent.group(); 50 | 51 | if (typeof value === 'string' || value instanceof String) { 52 | // value is a string 53 | var featText = group.plain(name).y(CURRENTY); 54 | var attrs = {'title': value, 55 | 'font-style': 'italic'}; 56 | 57 | if (name != 'CARG'){ 58 | // If it's not 'CARG' then it's a variable 59 | attrs['class'] = 'variable'; 60 | attrs['data-var'] = value; 61 | } 62 | 63 | var featVal = group.plain(value).move(FEATNAMEXGAP, CURRENTY).attr(attrs); 64 | } else if (Object.prototype.toString.call(value) === '[object Array]'){ 65 | // value is a list 66 | if (name == 'RELS') { 67 | var itemFunc = relFeatStruct; 68 | } else if (name == 'HCONS') { 69 | // filter out ICONS values from the constraints list 70 | var value = value.filter(constraint => constraint.high != null && constraint.high.match(/h(andle)?\d+/)); 71 | var itemFunc = hconsFeatStruct; 72 | } else if (name == 'ICONS') { 73 | // filter out HCONS values from the constraints list 74 | var value = value.filter(constraint => constraint.high == null || !constraint.high.match(/h(andle)?\d+/)); 75 | var itemFunc = iconsFeatStruct; 76 | } 77 | 78 | if (value.length == 0) 79 | // no constraints needed to render 80 | return null; 81 | 82 | var featText = group.plain(name); 83 | var list = drawList(group, value, itemFunc); 84 | var firstLine = list.select('g').first(); 85 | featText.cy(firstLine.tbox().cy); 86 | 87 | // transform the group to make space 88 | var diff = group.previous().tbox().y2 - list.tbox().y; 89 | if (diff > 0) 90 | group.transform({y:diff + YGAPSTRUCT}); 91 | } 92 | 93 | CURRENTY += group.tbox().height; 94 | return group; 95 | } 96 | 97 | function relFeatStruct(parent, rel) { 98 | var pred = rel['predicate'] +'⟨'+rel.lnk.from+':'+rel.lnk.to+'⟩'; 99 | drawFeatStructType(parent, pred); 100 | drawFeatValPair(parent, 'LBL', rel['label']); 101 | 102 | var args = Object.keys(rel.arguments).sort(rargcompare); 103 | 104 | for (var j=0; j < args.length; j++) { 105 | var arg = args[j]; 106 | drawFeatValPair(parent, arg, rel.arguments[arg]); 107 | } 108 | } 109 | 110 | function hconsFeatStruct(parent, hcon) { 111 | drawFeatStructType(parent, hcon.relation); 112 | drawFeatValPair(parent, 'HARG', hcon.high); 113 | drawFeatValPair(parent, 'LARG', hcon.low); 114 | } 115 | 116 | function iconsFeatStruct(parent, icon) { 117 | drawFeatStructType(parent, icon.relation); 118 | Object.keys(icon).forEach(function(key,index) { 119 | if (key == 'relation') 120 | return; 121 | drawFeatValPair(parent, key.toUpperCase(), icon[key]); 122 | }); 123 | } 124 | 125 | function drawList(parent, itemsData, itemFunc) { 126 | // The list may need to be broken up into multiple lines 127 | var lines = []; 128 | var startX = FEATNAMEXGAP + BRACKETXWIDTH; 129 | var currX = startX; 130 | var currY = 0; 131 | 132 | var list = parent.group(); 133 | var leftAngle = list.polyline(); 134 | var line = list.group(); 135 | 136 | // draw all the items. note that x and y coordinates for item drawing are 137 | // relative to the parent group containing the whole list 138 | for (var i=0; i < itemsData.length; i++) { 139 | CURRENTY = 0; 140 | var itemGroup = line.group(); 141 | 142 | itemFunc(itemGroup, itemsData[i]); 143 | drawSquareBrackets(itemGroup, 5); 144 | itemGroup.transform({x:currX, y:currY}); 145 | 146 | // update item offsets 147 | if (i == itemsData.length - 1) { 148 | // we're done with items 149 | break; 150 | } else if (currX >= MAXWIDTH) { 151 | // Starting a new line of items 152 | currX = startX; 153 | currY += line.tbox().height + YGAPSTRUCT; 154 | lines.push(line); 155 | line = list.group(); 156 | } else { 157 | // move along by last itemGroup width 158 | currX += itemGroup.tbox().width + 2*XGAP; 159 | } 160 | 161 | } 162 | lines.push(line); 163 | 164 | //vertically align the items in each line 165 | for (var i=0; i < lines.length; i++) { 166 | var thisLine = lines[i]; 167 | thisLine.cy = thisLine.tbox().cy; 168 | var items = thisLine.children(); 169 | 170 | for (var j=0; j < items.length; j++) { 171 | // align each item vertically and add vertically aligned comma. 172 | // need to account for negative y values using BRACKETYPAD 173 | var item = items[j]; 174 | item.cy(thisLine.cy + BRACKETYPAD); 175 | var tbox = item.tbox(); 176 | var comma = item.plain(',').center(tbox.width-1, -BRACKETYPAD + tbox.height/2); 177 | } 178 | } 179 | 180 | // remove trailing comma 181 | comma.remove(); 182 | 183 | var firstLine = lines[0]; 184 | 185 | //update left angle dimensions, now we know where the midpoint is 186 | var firstRelTbox = firstLine.children()[0].tbox(); 187 | leftAngle.plot([ 188 | [firstRelTbox.x - BRACKETXWIDTH, firstLine.cy + ANGLEHEIGHT/2], 189 | [firstRelTbox.x - BRACKETXWIDTH - ANGLEWIDTH, firstLine.cy], 190 | [firstRelTbox.x - BRACKETXWIDTH, firstLine.cy - ANGLEHEIGHT/2]]).fill('none').stroke('black'); 191 | 192 | //Add right angle bracket 193 | var lastLine = lines[lines.length - 1]; 194 | var lastLineTbox = lastLine.tbox(); 195 | var rightAngle = line.polyline([ 196 | [lastLineTbox.x2 + BRACKETXWIDTH, lastLine.cy + ANGLEHEIGHT/2], 197 | [lastLineTbox.x2 + BRACKETXWIDTH + ANGLEWIDTH, lastLine.cy], 198 | [lastLineTbox.x2 + BRACKETXWIDTH, lastLine.cy - ANGLEHEIGHT/2]]).fill('none').stroke('black'); 199 | 200 | return list; 201 | } 202 | 203 | function drawSquareBrackets(element, xpad) { 204 | // xpad -- distance bracket extends left/right of box 205 | 206 | // Draw left and right square brackets 207 | var tbox = element.tbox(); 208 | 209 | // left vertical line; top right angle; bottom right angle 210 | element.line(tbox.x-xpad, tbox.y-BRACKETYPAD, tbox.x-xpad, 211 | tbox.y2+BRACKETYPAD).stroke({width:1}); 212 | element.line(tbox.x-xpad, tbox.y-BRACKETYPAD, tbox.x-xpad+BRACKETXWIDTH, 213 | tbox.y-BRACKETYPAD).stroke({width:1}); 214 | element.line(tbox.x-xpad, tbox.y2+BRACKETYPAD, tbox.x-xpad+BRACKETXWIDTH, 215 | tbox.y2+BRACKETYPAD).stroke({width:1}); 216 | 217 | // left vertical line; top right angle; bottom right angle 218 | element.line(tbox.x2+xpad, tbox.y-BRACKETYPAD, tbox.x2+xpad, 219 | tbox.y2+BRACKETYPAD).stroke({width:1}); 220 | element.line(tbox.x2+xpad-BRACKETXWIDTH, tbox.y-BRACKETYPAD, tbox.x2+xpad, 221 | tbox.y-BRACKETYPAD).stroke({width:1}); 222 | element.line(tbox.x2+xpad-BRACKETXWIDTH, tbox.y2+BRACKETYPAD, tbox.x2+xpad, 223 | tbox.y2+BRACKETYPAD).stroke({width:1}); 224 | } 225 | 226 | function rargcompare(a, b) { 227 | // Compare function for sorting rel arguments 228 | var a = a.toUpperCase(); 229 | var b = b.toUpperCase(); 230 | if (a === 'BODY' || a === 'CARG' || a.substr(-4) === 'HNDL') { 231 | return 1; 232 | } else if (b === 'BODY' || b === 'CARG' || b.substr(-4) === 'HNDL') { 233 | return -1; 234 | } else { 235 | return a > b; 236 | } 237 | } 238 | 239 | function xArgKey(arg) { 240 | // Key function for x variable properties 241 | var arg = arg.toUpperCase(); 242 | var xvar = ['PERS', 'NUM', 'PT', 'IND']; 243 | var index = xvar.indexOf(arg); 244 | return index > 0 ? index: 9999; 245 | } 246 | 247 | function eArgKey(arg) { 248 | // Key function for event variable properties 249 | var arg = arg.toUpperCase(); 250 | var evar = ['SF', 'TENSE', 'MOOD', 'PROG', 'PERF']; 251 | var index = evar.indexOf(arg); 252 | return index > 0 ? index: 9999; 253 | } 254 | 255 | function keySort(array, func){ 256 | // Returns a copy of 'array' sorted based on first applying 'func' to 257 | // each element 258 | var mapped = array.map(function(el, i){ 259 | return {index: i, value: func(el)}; 260 | }); 261 | 262 | mapped.sort(function(a, b) { 263 | return +(a.value < b.value) || +(a.value === b.value) - 1; 264 | }); 265 | 266 | return mapped.map(function(el){ 267 | return array[el.index]; 268 | }); 269 | } 270 | 271 | function addHandlers(node){ 272 | $(node).find('.variable').hover( 273 | function (event){ 274 | event.stopPropagation(); 275 | var $this = $(this); 276 | 277 | // highlight variables 278 | var dataQuery = "[data-var='" + $this.data('var') + "']"; 279 | $(node).find(dataQuery).css({fill: 'red'}); 280 | 281 | // highlight input text span if variable has lnk data 282 | var lnks = argZeroes[this.innerHTML]; 283 | if (lnks == undefined) 284 | // no lnks for this variable 285 | return; 286 | 287 | var $inputElem = $('#text-input'); 288 | var inputText = $inputElem.html(); 289 | 290 | // create an arrary of binary values indicating which characters 291 | // should be highlighted 292 | var chars = Array.apply(null, Array(inputText.length)).map(function(){return 0}); 293 | for (var i=0; i < lnks.length; i++) { 294 | for (var j=lnks[i].from; j < lnks[i].to; j++) 295 | chars[j] = 1; 296 | } 297 | 298 | // create a list of highlighted or not highlighted tokens 299 | // to be joined together and then used to replace the text 300 | var tokens = []; 301 | var inside = false; 302 | var start = 0; 303 | for (var c=0; c < chars.length; c++){ 304 | var status = chars[c]; 305 | var atEnd = (c == chars.length - 1); 306 | var end = atEnd ? c+1 : c; 307 | if (inside && (!status || atEnd)) { 308 | tokens.push('' + inputText.slice(start, end) + ''); 309 | inside = false; 310 | start = c; 311 | } else if (!inside && (status || atEnd)) { 312 | tokens.push(inputText.slice(start, end)); 313 | inside = true; 314 | start = c; 315 | } 316 | } 317 | $inputElem.html(tokens.join('')); 318 | } 319 | , 320 | function (event){ 321 | // remove highlighted variables 322 | var dataQuery = "[data-var='" + $(this).data('var') + "']"; 323 | $(node).find(dataQuery).css({fill: 'black'}); 324 | 325 | // reset highlighted input string 326 | var $inputElem = $('#text-input'); 327 | $inputElem.html($inputElem.html().replace(/<\/?span[^>]*>/g,"")); 328 | } 329 | ).filter(function (){ 330 | // only draw tooltip for variables of type e and x probably should 331 | // be doing the test against whether corresponding mrs variable 332 | // object has "properties" field or not. 333 | var varName = $(this).data('var'); 334 | return mrsData.variables[varName].hasOwnProperty("properties"); 335 | }).tooltip({ 336 | track: true, 337 | tooltipClass: 'mrs-variable-info', 338 | content: function(){ 339 | var varName = $(this).data('var'); 340 | var variable = mrsData.variables[varName]; 341 | var func = variable.type == 'e' ? eArgKey : xArgKey; 342 | var features = keySort(Object.keys(variable.properties), func); 343 | 344 | var rows = []; 345 | for (var i=0; i < features.length; i++) { 346 | var attr = features[i]; 347 | rows.push(''+attr+''+variable.properties[attr]+''); 348 | } 349 | return '' + rows.join('') + '
'; 350 | } 351 | }); 352 | } 353 | 354 | function getArgZeroLinks(){ 355 | argZeroLinks = {}; 356 | 357 | for (var i=0; i < mrsData.relations.length; i++) { 358 | var rel = mrsData.relations[i]; 359 | if (argZeroLinks.hasOwnProperty(rel.arguments.ARG0)) 360 | argZeroLinks[rel.arguments.ARG0].push(rel.lnk); 361 | else 362 | argZeroLinks[rel.arguments.ARG0] = [rel.lnk]; 363 | } 364 | return argZeroLinks; 365 | } 366 | 367 | var argZeroes = getArgZeroLinks(); 368 | 369 | var self = { 370 | parent: parentElement, 371 | data: mrsData, 372 | element: drawMrs() 373 | }; 374 | 375 | addHandlers(self.element); 376 | return self; 377 | } 378 | -------------------------------------------------------------------------------- /demo/elephant.json: -------------------------------------------------------------------------------- 1 | {"input": "The boy saw the elephant in the park.", 2 | "readings": 10, "tcpu": 0.11, "pedges": 274, 3 | "results": [ 4 | {"result-id": 0, "score": 6.1850, 5 | "derivation": 6 | {"id": 985, "entity": "sb-hd_mc_c", "type": "subjh_mc_rule", "label": "S", "score": 6.18499, "daughters": [ 7 | {"id": 975, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": 1.1308, "daughters": [ 8 | {"id": 124, "entity": "the_1", "type": "d_-_the_le", "label": "DET", "score": -1.20374, 9 | "form": "the", "from": 0, "to": 3, "tokens": [ 10 | {"id": 103, "from": 0, "to": 3, "tfs": "token [ +CARG \"The\" +CLASS alphabetic [ +CASE capitalized+lower +INITIAL + ] +FORM \"the\" +FROM #1=\"0\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"1\" REST #2 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"3\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 11 | {"id": 974, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "label": "N", "score": 1.30259, "daughters": [ 12 | {"id": 149, "entity": "boy_n1", "type": "n_-_c_le", "label": "N", "score": 0, 13 | "form": "boy", "from": 4, "to": 7, "tokens": [ 14 | {"id": 86, "from": 4, "to": 7, "tfs": "token [ +CARG #1=\"boy\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"4\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"2\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"7\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}, 15 | {"id": 984, "entity": "hd-aj_int-unsl_c", "type": "hadj_i_unsl_rule", "label": "VP", "score": 3.88614, "daughters": [ 16 | {"id": 979, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "VP", "score": 2.43979, "daughters": [ 17 | {"id": 976, "entity": "v_pst_olr", "type": "v_pst_inflrule", "label": "V", "score": 1.26885, "daughters": [ 18 | {"id": 169, "entity": "see_v1", "type": "v_np_le", "label": "V", "score": 0.644025, 19 | "form": "saw", "from": 8, "to": 11, "tokens": [ 20 | {"id": 88, "from": 8, "to": 11, "tfs": "token [ +CARG #1=\"saw\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"8\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"3\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"VBD\" ] +PRBS *null* +TAGS *null* ] +TO \"11\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}, 21 | {"id": 978, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": 0.0257073, "daughters": [ 22 | {"id": 220, "entity": "the_1", "type": "d_-_the_le", "label": "DET", "score": -0.584076, 23 | "form": "the", "from": 12, "to": 15, "tokens": [ 24 | {"id": 90, "from": 12, "to": 15, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"12\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"4\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"15\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 25 | {"id": 977, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "label": "N", "score": 0.549305, "daughters": [ 26 | {"id": 245, "entity": "elephant_n1", "type": "n_-_c_le", "label": "N", "score": 0, 27 | "form": "elephant", "from": 16, "to": 24, "tokens": [ 28 | {"id": 92, "from": 16, "to": 24, "tfs": "token [ +CARG #1=\"elephant\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"16\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"5\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"24\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}]}, 29 | {"id": 983, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "PP", "score": 0.869804, "daughters": [ 30 | {"id": 266, "entity": "in", "type": "p_np_i-reg_le", "label": "P", "score": -0.674781, 31 | "form": "in", "from": 25, "to": 27, "tokens": [ 32 | {"id": 94, "from": 25, "to": 27, "tfs": "token [ +CARG #1=\"in\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"25\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"6\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"IN\" ] +PRBS *null* +TAGS *null* ] +TO \"27\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 33 | {"id": 982, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": 1.43807, "daughters": [ 34 | {"id": 319, "entity": "the_1", "type": "d_-_the_le", "label": "DET", "score": -0.684339, 35 | "form": "the", "from": 28, "to": 31, "tokens": [ 36 | {"id": 96, "from": 28, "to": 31, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"28\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"7\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"31\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 37 | {"id": 981, "entity": "w_period_plr", "type": "punctuation_period_rule", "label": "N", "score": 2.0433, "daughters": [ 38 | {"id": 980, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "label": "N", "score": 1.33401, "daughters": [ 39 | {"id": 345, "entity": "park_n1", "type": "n_-_c_le", "label": "N", "score": 0.308703, 40 | "form": "park.", "from": 32, "to": 37, "tokens": [ 41 | {"id": 98, "from": 32, "to": 37, "tfs": "token [ +CARG \"park\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM \"park.\" +FROM #1=\"32\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"8\" REST *cons* [ FIRST \"9\" REST #2 ] ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"37\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}]}]}]}]}, 42 | "mrs": 43 | {"top": "h1", 44 | "index": "e3", 45 | "relations": 46 | [{"label": "h4", "predicate": "_the_q", "lnk": {"from": 0, "to": 3}, "arguments": 47 | {"ARG0": "x6", "RSTR": "h7", "BODY": "h5"}}, 48 | {"label": "h8", "predicate": "_boy_n_1", "lnk": {"from": 4, "to": 7}, "arguments": 49 | {"ARG0": "x6"}}, 50 | {"label": "h2", "predicate": "_see_v_1", "lnk": {"from": 8, "to": 11}, "arguments": 51 | {"ARG0": "e3", "ARG1": "x6", "ARG2": "x9"}}, 52 | {"label": "h10", "predicate": "_the_q", "lnk": {"from": 12, "to": 15}, "arguments": 53 | {"ARG0": "x9", "RSTR": "h12", "BODY": "h11"}}, 54 | {"label": "h13", "predicate": "_elephant_n_1", "lnk": {"from": 16, "to": 24}, "arguments": 55 | {"ARG0": "x9"}}, 56 | {"label": "h2", "predicate": "_in_p", "lnk": {"from": 25, "to": 27}, "arguments": 57 | {"ARG0": "e14", "ARG1": "e3", "ARG2": "x15"}}, 58 | {"label": "h16", "predicate": "_the_q", "lnk": {"from": 28, "to": 31}, "arguments": 59 | {"ARG0": "x15", "RSTR": "h18", "BODY": "h17"}}, 60 | {"label": "h19", "predicate": "_park_n_1", "lnk": {"from": 32, "to": 37}, "arguments": 61 | {"ARG0": "x15"}}], 62 | "constraints": 63 | [{"relation": "qeq", "high": "h1", "low": "h2"}, 64 | {"relation": "qeq", "high": "h7", "low": "h8"}, 65 | {"relation": "qeq", "high": "h12", "low": "h13"}, 66 | {"relation": "qeq", "high": "h18", "low": "h19"}], 67 | "variables": 68 | {"h19": {"type": "h"}, "h17": {"type": "h"}, "h18": {"type": "h"}, 69 | "h16": {"type": "h"}, 70 | "x15": {"type": "x", "properties": 71 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 72 | "e14": {"type": "e", "properties": 73 | {"SF": "prop", "TENSE": "untensed", "MOOD": "indicative", 74 | "PROG": "-", "PERF": "-"}}, 75 | "h13": {"type": "h"}, "h11": {"type": "h"}, "h12": {"type": "h"}, 76 | "h10": {"type": "h"}, 77 | "x9": {"type": "x", "properties": 78 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 79 | "h2": {"type": "h"}, "h8": {"type": "h"}, "h5": {"type": "h"}, 80 | "h7": {"type": "h"}, 81 | "x6": {"type": "x", "properties": 82 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 83 | "h4": {"type": "h"}, 84 | "e3": {"type": "e", "properties": 85 | {"SF": "prop", "TENSE": "past", "MOOD": "indicative", "PROG": "-", 86 | "PERF": "-"}}, 87 | "h1": {"type": "h"}}}}, 88 | {"result-id": 1, "score": 5.7650, 89 | "derivation": 90 | {"id": 989, "entity": "sb-hd_mc_c", "type": "subjh_mc_rule", "label": "S", "score": 5.76496, "daughters": [ 91 | {"id": 975, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": 1.1308, "daughters": [ 92 | {"id": 124, "entity": "the_1", "type": "d_-_the_le", "score": -1.20374, 93 | "form": "the", "from": 0, "to": 3, "tokens": [ 94 | {"id": 103, "from": 0, "to": 3, "tfs": "token [ +CARG \"The\" +CLASS alphabetic [ +CASE capitalized+lower +INITIAL + ] +FORM \"the\" +FROM #1=\"0\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"1\" REST #2 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"3\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 95 | {"id": 974, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": 1.30259, "daughters": [ 96 | {"id": 149, "entity": "boy_n1", "type": "n_-_c_le", "score": 0, 97 | "form": "boy", "from": 4, "to": 7, "tokens": [ 98 | {"id": 86, "from": 4, "to": 7, "tfs": "token [ +CARG #1=\"boy\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"4\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"2\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"7\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}, 99 | {"id": 988, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "VP", "score": 3.09823, "daughters": [ 100 | {"id": 987, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "V", "score": 0.962965, "daughters": [ 101 | {"id": 986, "entity": "v_pst_olr", "type": "v_pst_inflrule", "label": "V", "score": 0.0408252, "daughters": [ 102 | {"id": 175, "entity": "see_v7", "type": "v_np-prd_oeq_le", "label": "V", "score": 0.623957, 103 | "form": "saw", "from": 8, "to": 11, "tokens": [ 104 | {"id": 88, "from": 8, "to": 11, "tfs": "token [ +CARG #1=\"saw\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"8\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"3\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"VBD\" ] +PRBS *null* +TAGS *null* ] +TO \"11\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}, 105 | {"id": 978, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": 0.0257073, "daughters": [ 106 | {"id": 220, "entity": "the_1", "type": "d_-_the_le", "score": -0.584076, 107 | "form": "the", "from": 12, "to": 15, "tokens": [ 108 | {"id": 90, "from": 12, "to": 15, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"12\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"4\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"15\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 109 | {"id": 977, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": 0.549305, "daughters": [ 110 | {"id": 245, "entity": "elephant_n1", "type": "n_-_c_le", "score": 0, 111 | "form": "elephant", "from": 16, "to": 24, "tokens": [ 112 | {"id": 92, "from": 16, "to": 24, "tfs": "token [ +CARG #1=\"elephant\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"16\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"5\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"24\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}]}, 113 | {"id": 983, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "PP", "score": 0.869804, "daughters": [ 114 | {"id": 266, "entity": "in", "type": "p_np_i-reg_le", "score": -0.674781, 115 | "form": "in", "from": 25, "to": 27, "tokens": [ 116 | {"id": 94, "from": 25, "to": 27, "tfs": "token [ +CARG #1=\"in\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"25\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"6\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"IN\" ] +PRBS *null* +TAGS *null* ] +TO \"27\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 117 | {"id": 982, "entity": "sp-hd_n_c", "type": "hspec_rule", "score": 1.43807, "daughters": [ 118 | {"id": 319, "entity": "the_1", "type": "d_-_the_le", "score": -0.684339, 119 | "form": "the", "from": 28, "to": 31, "tokens": [ 120 | {"id": 96, "from": 28, "to": 31, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"28\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"7\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"31\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 121 | {"id": 981, "entity": "w_period_plr", "type": "punctuation_period_rule", "score": 2.0433, "daughters": [ 122 | {"id": 980, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": 1.33401, "daughters": [ 123 | {"id": 345, "entity": "park_n1", "type": "n_-_c_le", "score": 0.308703, 124 | "form": "park.", "from": 32, "to": 37, "tokens": [ 125 | {"id": 98, "from": 32, "to": 37, "tfs": "token [ +CARG \"park\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM \"park.\" +FROM #1=\"32\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"8\" REST *cons* [ FIRST \"9\" REST #2 ] ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"37\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}]}]}]}]}, 126 | "mrs": 127 | {"top": "h1", 128 | "index": "e3", 129 | "relations": 130 | [{"label": "h4", "predicate": "_the_q", "lnk": {"from": 0, "to": 3}, "arguments": 131 | {"ARG0": "x6", "RSTR": "h7", "BODY": "h5"}}, 132 | {"label": "h8", "predicate": "_boy_n_1", "lnk": {"from": 4, "to": 7}, "arguments": 133 | {"ARG0": "x6"}}, 134 | {"label": "h2", "predicate": "_see_v_1", "lnk": {"from": 8, "to": 11}, "arguments": 135 | {"ARG0": "e3", "ARG1": "x6", "ARG2": "x10", "ARG3": "h9"}}, 136 | {"label": "h11", "predicate": "_the_q", "lnk": {"from": 12, "to": 15}, "arguments": 137 | {"ARG0": "x10", "RSTR": "h13", "BODY": "h12"}}, 138 | {"label": "h14", "predicate": "_elephant_n_1", "lnk": {"from": 16, "to": 24}, "arguments": 139 | {"ARG0": "x10"}}, 140 | {"label": "h15", "predicate": "_in_p", "lnk": {"from": 25, "to": 27}, "arguments": 141 | {"ARG0": "e16", "ARG1": "x10", "ARG2": "x17"}}, 142 | {"label": "h18", "predicate": "_the_q", "lnk": {"from": 28, "to": 31}, "arguments": 143 | {"ARG0": "x17", "RSTR": "h20", "BODY": "h19"}}, 144 | {"label": "h21", "predicate": "_park_n_1", "lnk": {"from": 32, "to": 37}, "arguments": 145 | {"ARG0": "x17"}}], 146 | "constraints": 147 | [{"relation": "qeq", "high": "h1", "low": "h2"}, 148 | {"relation": "qeq", "high": "h7", "low": "h8"}, 149 | {"relation": "qeq", "high": "h9", "low": "h15"}, 150 | {"relation": "qeq", "high": "h13", "low": "h14"}, 151 | {"relation": "qeq", "high": "h20", "low": "h21"}], 152 | "variables": 153 | {"h21": {"type": "h"}, "h19": {"type": "h"}, "h20": {"type": "h"}, 154 | "h18": {"type": "h"}, 155 | "x17": {"type": "x", "properties": 156 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 157 | "e16": {"type": "e", "properties": 158 | {"SF": "prop", "TENSE": "untensed", "MOOD": "indicative", 159 | "PROG": "-", "PERF": "-"}}, 160 | "h15": {"type": "h"}, "h14": {"type": "h"}, "h12": {"type": "h"}, 161 | "h13": {"type": "h"}, "h11": {"type": "h"}, "h9": {"type": "h"}, 162 | "x10": {"type": "x", "properties": 163 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 164 | "h2": {"type": "h"}, "h8": {"type": "h"}, "h5": {"type": "h"}, 165 | "h7": {"type": "h"}, 166 | "x6": {"type": "x", "properties": 167 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 168 | "h4": {"type": "h"}, 169 | "e3": {"type": "e", "properties": 170 | {"SF": "prop", "TENSE": "past", "MOOD": "indicative", "PROG": "-", 171 | "PERF": "-"}}, 172 | "h1": {"type": "h"}}}}, 173 | {"result-id": 2, "score": 5.6250, 174 | "derivation": 175 | {"id": 993, "entity": "sb-hd_mc_c", "type": "subjh_mc_rule", "label": "S", "score": 5.62538, "daughters": [ 176 | {"id": 975, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": 1.1308, "daughters": [ 177 | {"id": 124, "entity": "the_1", "type": "d_-_the_le", "score": -1.20374, 178 | "form": "the", "from": 0, "to": 3, "tokens": [ 179 | {"id": 103, "from": 0, "to": 3, "tfs": "token [ +CARG \"The\" +CLASS alphabetic [ +CASE capitalized+lower +INITIAL + ] +FORM \"the\" +FROM #1=\"0\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"1\" REST #2 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"3\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 180 | {"id": 974, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": 1.30259, "daughters": [ 181 | {"id": 149, "entity": "boy_n1", "type": "n_-_c_le", "score": 0, 182 | "form": "boy", "from": 4, "to": 7, "tokens": [ 183 | {"id": 86, "from": 4, "to": 7, "tfs": "token [ +CARG #1=\"boy\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"4\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"2\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"7\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}, 184 | {"id": 992, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "VP", "score": 2.95866, "daughters": [ 185 | {"id": 976, "entity": "v_pst_olr", "type": "v_pst_inflrule", "label": "V", "score": 1.26885, "daughters": [ 186 | {"id": 169, "entity": "see_v1", "type": "v_np_le", "score": 0.644025, 187 | "form": "saw", "from": 8, "to": 11, "tokens": [ 188 | {"id": 88, "from": 8, "to": 11, "tfs": "token [ +CARG #1=\"saw\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"8\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"3\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"VBD\" ] +PRBS *null* +TAGS *null* ] +TO \"11\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}, 189 | {"id": 991, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": 2.03027, "daughters": [ 190 | {"id": 220, "entity": "the_1", "type": "d_-_the_le", "label": "DET", "score": -0.584076, 191 | "form": "the", "from": 12, "to": 15, "tokens": [ 192 | {"id": 90, "from": 12, "to": 15, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"12\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"4\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"15\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 193 | {"id": 990, "entity": "hdn-aj_redrel_c", "type": "hadj_i_redrel_npr_rule", "label": "N", "score": 2.91223, "daughters": [ 194 | {"id": 977, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "label": "N", "score": 0.549305, "daughters": [ 195 | {"id": 245, "entity": "elephant_n1", "type": "n_-_c_le", "score": 0, 196 | "form": "elephant", "from": 16, "to": 24, "tokens": [ 197 | {"id": 92, "from": 16, "to": 24, "tfs": "token [ +CARG #1=\"elephant\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"16\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"5\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"24\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}, 198 | {"id": 983, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "PP", "score": 0.869804, "daughters": [ 199 | {"id": 266, "entity": "in", "type": "p_np_i-reg_le", "score": -0.674781, 200 | "form": "in", "from": 25, "to": 27, "tokens": [ 201 | {"id": 94, "from": 25, "to": 27, "tfs": "token [ +CARG #1=\"in\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"25\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"6\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"IN\" ] +PRBS *null* +TAGS *null* ] +TO \"27\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 202 | {"id": 982, "entity": "sp-hd_n_c", "type": "hspec_rule", "score": 1.43807, "daughters": [ 203 | {"id": 319, "entity": "the_1", "type": "d_-_the_le", "score": -0.684339, 204 | "form": "the", "from": 28, "to": 31, "tokens": [ 205 | {"id": 96, "from": 28, "to": 31, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"28\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"7\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"31\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 206 | {"id": 981, "entity": "w_period_plr", "type": "punctuation_period_rule", "score": 2.0433, "daughters": [ 207 | {"id": 980, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": 1.33401, "daughters": [ 208 | {"id": 345, "entity": "park_n1", "type": "n_-_c_le", "score": 0.308703, 209 | "form": "park.", "from": 32, "to": 37, "tokens": [ 210 | {"id": 98, "from": 32, "to": 37, "tfs": "token [ +CARG \"park\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM \"park.\" +FROM #1=\"32\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"8\" REST *cons* [ FIRST \"9\" REST #2 ] ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"37\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}]}]}]}]}]}]}, 211 | "mrs": 212 | {"top": "h1", 213 | "index": "e3", 214 | "relations": 215 | [{"label": "h4", "predicate": "_the_q", "lnk": {"from": 0, "to": 3}, "arguments": 216 | {"ARG0": "x6", "RSTR": "h7", "BODY": "h5"}}, 217 | {"label": "h8", "predicate": "_boy_n_1", "lnk": {"from": 4, "to": 7}, "arguments": 218 | {"ARG0": "x6"}}, 219 | {"label": "h2", "predicate": "_see_v_1", "lnk": {"from": 8, "to": 11}, "arguments": 220 | {"ARG0": "e3", "ARG1": "x6", "ARG2": "x9"}}, 221 | {"label": "h10", "predicate": "_the_q", "lnk": {"from": 12, "to": 15}, "arguments": 222 | {"ARG0": "x9", "RSTR": "h12", "BODY": "h11"}}, 223 | {"label": "h13", "predicate": "_elephant_n_1", "lnk": {"from": 16, "to": 24}, "arguments": 224 | {"ARG0": "x9"}}, 225 | {"label": "h13", "predicate": "_in_p", "lnk": {"from": 25, "to": 27}, "arguments": 226 | {"ARG0": "e14", "ARG1": "x9", "ARG2": "x15"}}, 227 | {"label": "h16", "predicate": "_the_q", "lnk": {"from": 28, "to": 31}, "arguments": 228 | {"ARG0": "x15", "RSTR": "h18", "BODY": "h17"}}, 229 | {"label": "h19", "predicate": "_park_n_1", "lnk": {"from": 32, "to": 37}, "arguments": 230 | {"ARG0": "x15"}}], 231 | "constraints": 232 | [{"relation": "qeq", "high": "h1", "low": "h2"}, 233 | {"relation": "qeq", "high": "h7", "low": "h8"}, 234 | {"relation": "qeq", "high": "h12", "low": "h13"}, 235 | {"relation": "qeq", "high": "h18", "low": "h19"}], 236 | "variables": 237 | {"h19": {"type": "h"}, "h17": {"type": "h"}, "h18": {"type": "h"}, 238 | "h16": {"type": "h"}, 239 | "x15": {"type": "x", "properties": 240 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 241 | "e14": {"type": "e", "properties": 242 | {"SF": "prop", "TENSE": "untensed", "MOOD": "indicative", 243 | "PROG": "-", "PERF": "-"}}, 244 | "h13": {"type": "h"}, "h11": {"type": "h"}, "h12": {"type": "h"}, 245 | "h10": {"type": "h"}, 246 | "x9": {"type": "x", "properties": 247 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 248 | "h2": {"type": "h"}, "h8": {"type": "h"}, "h5": {"type": "h"}, 249 | "h7": {"type": "h"}, 250 | "x6": {"type": "x", "properties": 251 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 252 | "h4": {"type": "h"}, 253 | "e3": {"type": "e", "properties": 254 | {"SF": "prop", "TENSE": "past", "MOOD": "indicative", "PROG": "-", 255 | "PERF": "-"}}, 256 | "h1": {"type": "h"}}}}, 257 | {"result-id": 3, "score": 3.2990, 258 | "derivation": 259 | {"id": 999, "entity": "sb-hd_mc_c", "type": "subjh_mc_rule", "label": "S", "score": 3.29914, "daughters": [ 260 | {"id": 975, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": 1.1308, "daughters": [ 261 | {"id": 124, "entity": "the_1", "type": "d_-_the_le", "score": -1.20374, 262 | "form": "the", "from": 0, "to": 3, "tokens": [ 263 | {"id": 103, "from": 0, "to": 3, "tfs": "token [ +CARG \"The\" +CLASS alphabetic [ +CASE capitalized+lower +INITIAL + ] +FORM \"the\" +FROM #1=\"0\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"1\" REST #2 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"3\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 264 | {"id": 974, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": 1.30259, "daughters": [ 265 | {"id": 149, "entity": "boy_n1", "type": "n_-_c_le", "score": 0, 266 | "form": "boy", "from": 4, "to": 7, "tokens": [ 267 | {"id": 86, "from": 4, "to": 7, "tfs": "token [ +CARG #1=\"boy\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"4\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"2\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"7\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}, 268 | {"id": 998, "entity": "hd-aj_int-unsl_c", "type": "hadj_i_unsl_rule", "label": "VP", "score": 1.00029, "daughters": [ 269 | {"id": 979, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "VP", "score": 2.43979, "daughters": [ 270 | {"id": 976, "entity": "v_pst_olr", "type": "v_pst_inflrule", "score": 1.26885, "daughters": [ 271 | {"id": 169, "entity": "see_v1", "type": "v_np_le", "score": 0.644025, 272 | "form": "saw", "from": 8, "to": 11, "tokens": [ 273 | {"id": 88, "from": 8, "to": 11, "tfs": "token [ +CARG #1=\"saw\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"8\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"3\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"VBD\" ] +PRBS *null* +TAGS *null* ] +TO \"11\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}, 274 | {"id": 978, "entity": "sp-hd_n_c", "type": "hspec_rule", "score": 0.0257073, "daughters": [ 275 | {"id": 220, "entity": "the_1", "type": "d_-_the_le", "score": -0.584076, 276 | "form": "the", "from": 12, "to": 15, "tokens": [ 277 | {"id": 90, "from": 12, "to": 15, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"12\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"4\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"15\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 278 | {"id": 977, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": 0.549305, "daughters": [ 279 | {"id": 245, "entity": "elephant_n1", "type": "n_-_c_le", "score": 0, 280 | "form": "elephant", "from": 16, "to": 24, "tokens": [ 281 | {"id": 92, "from": 16, "to": 24, "tfs": "token [ +CARG #1=\"elephant\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"16\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"5\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"24\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}]}, 282 | {"id": 997, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "PP", "score": -2.01605, "daughters": [ 283 | {"id": 266, "entity": "in", "type": "p_np_i-reg_le", "label": "P", "score": -0.674781, 284 | "form": "in", "from": 25, "to": 27, "tokens": [ 285 | {"id": 94, "from": 25, "to": 27, "tfs": "token [ +CARG #1=\"in\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"25\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"6\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"IN\" ] +PRBS *null* +TAGS *null* ] +TO \"27\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 286 | {"id": 996, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": -1.44778, "daughters": [ 287 | {"id": 319, "entity": "the_1", "type": "d_-_the_le", "label": "DET", "score": -0.684339, 288 | "form": "the", "from": 28, "to": 31, "tokens": [ 289 | {"id": 96, "from": 28, "to": 31, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"28\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"7\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"31\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 290 | {"id": 995, "entity": "w_period_plr", "type": "punctuation_period_rule", "label": "N", "score": -0.842548, "daughters": [ 291 | {"id": 994, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "label": "N", "score": -1.55184, "daughters": [ 292 | {"id": 346, "entity": "park_n2", "type": "n_-_pn_le", "label": "N", "score": -0.393003, 293 | "form": "park.", "from": 32, "to": 37, "tokens": [ 294 | {"id": 98, "from": 32, "to": 37, "tfs": "token [ +CARG \"park\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM \"park.\" +FROM #1=\"32\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"8\" REST *cons* [ FIRST \"9\" REST #2 ] ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"37\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}]}]}]}]}, 295 | "mrs": 296 | {"top": "h1", 297 | "index": "e3", 298 | "relations": 299 | [{"label": "h4", "predicate": "_the_q", "lnk": {"from": 0, "to": 3}, "arguments": 300 | {"ARG0": "x6", "RSTR": "h7", "BODY": "h5"}}, 301 | {"label": "h8", "predicate": "_boy_n_1", "lnk": {"from": 4, "to": 7}, "arguments": 302 | {"ARG0": "x6"}}, 303 | {"label": "h2", "predicate": "_see_v_1", "lnk": {"from": 8, "to": 11}, "arguments": 304 | {"ARG0": "e3", "ARG1": "x6", "ARG2": "x9"}}, 305 | {"label": "h10", "predicate": "_the_q", "lnk": {"from": 12, "to": 15}, "arguments": 306 | {"ARG0": "x9", "RSTR": "h12", "BODY": "h11"}}, 307 | {"label": "h13", "predicate": "_elephant_n_1", "lnk": {"from": 16, "to": 24}, "arguments": 308 | {"ARG0": "x9"}}, 309 | {"label": "h2", "predicate": "_in_p", "lnk": {"from": 25, "to": 27}, "arguments": 310 | {"ARG0": "e14", "ARG1": "e3", "ARG2": "x15"}}, 311 | {"label": "h16", "predicate": "_the_q", "lnk": {"from": 28, "to": 31}, "arguments": 312 | {"ARG0": "x15", "RSTR": "h18", "BODY": "h17"}}, 313 | {"label": "h19", "predicate": "named", "lnk": {"from": 32, "to": 37}, "arguments": 314 | {"ARG0": "x15", "CARG": "Park"}}], 315 | "constraints": 316 | [{"relation": "qeq", "high": "h1", "low": "h2"}, 317 | {"relation": "qeq", "high": "h7", "low": "h8"}, 318 | {"relation": "qeq", "high": "h12", "low": "h13"}, 319 | {"relation": "qeq", "high": "h18", "low": "h19"}], 320 | "variables": 321 | {"h19": {"type": "h"}, "h17": {"type": "h"}, "h18": {"type": "h"}, 322 | "h16": {"type": "h"}, 323 | "x15": {"type": "x", "properties": 324 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 325 | "e14": {"type": "e", "properties": 326 | {"SF": "prop", "TENSE": "untensed", "MOOD": "indicative", 327 | "PROG": "-", "PERF": "-"}}, 328 | "h13": {"type": "h"}, "h11": {"type": "h"}, "h12": {"type": "h"}, 329 | "h10": {"type": "h"}, 330 | "x9": {"type": "x", "properties": 331 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 332 | "h2": {"type": "h"}, "h8": {"type": "h"}, "h5": {"type": "h"}, 333 | "h7": {"type": "h"}, 334 | "x6": {"type": "x", "properties": 335 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 336 | "h4": {"type": "h"}, 337 | "e3": {"type": "e", "properties": 338 | {"SF": "prop", "TENSE": "past", "MOOD": "indicative", "PROG": "-", 339 | "PERF": "-"}}, 340 | "h1": {"type": "h"}}}}, 341 | {"result-id": 4, "score": 2.8790, 342 | "derivation": 343 | {"id": 1001, "entity": "sb-hd_mc_c", "type": "subjh_mc_rule", "label": "S", "score": 2.8791, "daughters": [ 344 | {"id": 975, "entity": "sp-hd_n_c", "type": "hspec_rule", "label": "NP", "score": 1.1308, "daughters": [ 345 | {"id": 124, "entity": "the_1", "type": "d_-_the_le", "score": -1.20374, 346 | "form": "the", "from": 0, "to": 3, "tokens": [ 347 | {"id": 103, "from": 0, "to": 3, "tfs": "token [ +CARG \"The\" +CLASS alphabetic [ +CASE capitalized+lower +INITIAL + ] +FORM \"the\" +FROM #1=\"0\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"1\" REST #2 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"3\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 348 | {"id": 974, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": 1.30259, "daughters": [ 349 | {"id": 149, "entity": "boy_n1", "type": "n_-_c_le", "score": 0, 350 | "form": "boy", "from": 4, "to": 7, "tokens": [ 351 | {"id": 86, "from": 4, "to": 7, "tfs": "token [ +CARG #1=\"boy\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"4\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"2\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"7\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}, 352 | {"id": 1000, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "VP", "score": 0.212381, "daughters": [ 353 | {"id": 987, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "V", "score": 0.962965, "daughters": [ 354 | {"id": 986, "entity": "v_pst_olr", "type": "v_pst_inflrule", "score": 0.0408252, "daughters": [ 355 | {"id": 175, "entity": "see_v7", "type": "v_np-prd_oeq_le", "score": 0.623957, 356 | "form": "saw", "from": 8, "to": 11, "tokens": [ 357 | {"id": 88, "from": 8, "to": 11, "tfs": "token [ +CARG #1=\"saw\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"8\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"3\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"VBD\" ] +PRBS *null* +TAGS *null* ] +TO \"11\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}, 358 | {"id": 978, "entity": "sp-hd_n_c", "type": "hspec_rule", "score": 0.0257073, "daughters": [ 359 | {"id": 220, "entity": "the_1", "type": "d_-_the_le", "score": -0.584076, 360 | "form": "the", "from": 12, "to": 15, "tokens": [ 361 | {"id": 90, "from": 12, "to": 15, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"12\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"4\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"15\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 362 | {"id": 977, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": 0.549305, "daughters": [ 363 | {"id": 245, "entity": "elephant_n1", "type": "n_-_c_le", "score": 0, 364 | "form": "elephant", "from": 16, "to": 24, "tokens": [ 365 | {"id": 92, "from": 16, "to": 24, "tfs": "token [ +CARG #1=\"elephant\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"16\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"5\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"24\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}]}, 366 | {"id": 997, "entity": "hd-cmp_u_c", "type": "hcomp_rule", "label": "PP", "score": -2.01605, "daughters": [ 367 | {"id": 266, "entity": "in", "type": "p_np_i-reg_le", "score": -0.674781, 368 | "form": "in", "from": 25, "to": 27, "tokens": [ 369 | {"id": 94, "from": 25, "to": 27, "tfs": "token [ +CARG #1=\"in\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"25\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"6\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"IN\" ] +PRBS *null* +TAGS *null* ] +TO \"27\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 370 | {"id": 996, "entity": "sp-hd_n_c", "type": "hspec_rule", "score": -1.44778, "daughters": [ 371 | {"id": 319, "entity": "the_1", "type": "d_-_the_le", "score": -0.684339, 372 | "form": "the", "from": 28, "to": 31, "tokens": [ 373 | {"id": 96, "from": 28, "to": 31, "tfs": "token [ +CARG #1=\"the\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM #1 +FROM #2=\"28\" +ID *diff-list* [ LAST #3=*list* LIST *cons* [ FIRST \"7\" REST #3 ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"DT\" ] +PRBS *null* +TAGS *null* ] +TO \"31\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #2 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}, 374 | {"id": 995, "entity": "w_period_plr", "type": "punctuation_period_rule", "score": -0.842548, "daughters": [ 375 | {"id": 994, "entity": "n_sg_ilr", "type": "n_sg_inflrule", "score": -1.55184, "daughters": [ 376 | {"id": 346, "entity": "park_n2", "type": "n_-_pn_le", "score": -0.393003, 377 | "form": "park.", "from": 32, "to": 37, "tokens": [ 378 | {"id": 98, "from": 32, "to": 37, "tfs": "token [ +CARG \"park\" +CLASS alphabetic [ +CASE non_capitalized+lower +INITIAL - ] +FORM \"park.\" +FROM #1=\"32\" +ID *diff-list* [ LAST #2=*list* LIST *cons* [ FIRST \"8\" REST *cons* [ FIRST \"9\" REST #2 ] ] ] +PRED predsort +TICK bool +TNT null_tnt [ +MAIN tnt_main [ +PRB \"1\" +TAG \"NN\" ] +PRBS *null* +TAGS *null* ] +TO \"37\" +TRAIT token_trait [ +HD token_head [ +LL ctype [ -CTYPE- string ] +TG string +TI #1 ] +IT italics +LB bracket_null +RB bracket_null +UW - ] ]"}]}]}]}]}]}]}]}, 379 | "mrs": 380 | {"top": "h1", 381 | "index": "e3", 382 | "relations": 383 | [{"label": "h4", "predicate": "_the_q", "lnk": {"from": 0, "to": 3}, "arguments": 384 | {"ARG0": "x6", "RSTR": "h7", "BODY": "h5"}}, 385 | {"label": "h8", "predicate": "_boy_n_1", "lnk": {"from": 4, "to": 7}, "arguments": 386 | {"ARG0": "x6"}}, 387 | {"label": "h2", "predicate": "_see_v_1", "lnk": {"from": 8, "to": 11}, "arguments": 388 | {"ARG0": "e3", "ARG1": "x6", "ARG2": "x10", "ARG3": "h9"}}, 389 | {"label": "h11", "predicate": "_the_q", "lnk": {"from": 12, "to": 15}, "arguments": 390 | {"ARG0": "x10", "RSTR": "h13", "BODY": "h12"}}, 391 | {"label": "h14", "predicate": "_elephant_n_1", "lnk": {"from": 16, "to": 24}, "arguments": 392 | {"ARG0": "x10"}}, 393 | {"label": "h15", "predicate": "_in_p", "lnk": {"from": 25, "to": 27}, "arguments": 394 | {"ARG0": "e16", "ARG1": "x10", "ARG2": "x17"}}, 395 | {"label": "h18", "predicate": "_the_q", "lnk": {"from": 28, "to": 31}, "arguments": 396 | {"ARG0": "x17", "RSTR": "h20", "BODY": "h19"}}, 397 | {"label": "h21", "predicate": "named", "lnk": {"from": 32, "to": 37}, "arguments": 398 | {"ARG0": "x17", "CARG": "Park"}}], 399 | "constraints": 400 | [{"relation": "qeq", "high": "h1", "low": "h2"}, 401 | {"relation": "qeq", "high": "h7", "low": "h8"}, 402 | {"relation": "qeq", "high": "h9", "low": "h15"}, 403 | {"relation": "qeq", "high": "h13", "low": "h14"}, 404 | {"relation": "qeq", "high": "h20", "low": "h21"}], 405 | "variables": 406 | {"h21": {"type": "h"}, "h19": {"type": "h"}, "h20": {"type": "h"}, 407 | "h18": {"type": "h"}, 408 | "x17": {"type": "x", "properties": 409 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 410 | "e16": {"type": "e", "properties": 411 | {"SF": "prop", "TENSE": "untensed", "MOOD": "indicative", 412 | "PROG": "-", "PERF": "-"}}, 413 | "h15": {"type": "h"}, "h14": {"type": "h"}, "h12": {"type": "h"}, 414 | "h13": {"type": "h"}, "h11": {"type": "h"}, "h9": {"type": "h"}, 415 | "x10": {"type": "x", "properties": 416 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 417 | "h2": {"type": "h"}, "h8": {"type": "h"}, "h5": {"type": "h"}, 418 | "h7": {"type": "h"}, 419 | "x6": {"type": "x", "properties": 420 | {"PERS": "3", "NUM": "sg", "IND": "+"}}, 421 | "h4": {"type": "h"}, 422 | "e3": {"type": "e", "properties": 423 | {"SF": "prop", "TENSE": "past", "MOOD": "indicative", "PROG": "-", 424 | "PERF": "-"}}, 425 | "h1": {"type": "h"}}}}]} 426 | --------------------------------------------------------------------------------