1 """Modality hierarchy for the jazz grammars.
2
3 This provides classes for defining a hierarchy of modalities that
4 will be used in a particular version of the grammar. This is not
5 formalism-specific, since the hierarchy itself is entirely defined
6 by the XML, even though some formalisms don't use modalities at all.
7
8 This also provides an abstract class the slashes with modalities on
9 them should inherit from.
10
11 """
12 """
13 ============================== License ========================================
14 Copyright (C) 2008, 2010-12 University of Edinburgh, Mark Granroth-Wilding
15
16 This file is part of The Jazz Parser.
17
18 The Jazz Parser is free software: you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation, either version 3 of the License, or
21 (at your option) any later version.
22
23 The Jazz Parser is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with The Jazz Parser. If not, see <http://www.gnu.org/licenses/>.
30
31 ============================ End license ======================================
32
33 """
34 __author__ = "Mark Granroth-Wilding <mark.granroth-wilding@ed.ac.uk>"
35
36 from xml.dom import Node
39 """
40 A node in the modality tree.
41
42 """
43 - def __init__(self, modality, children=None):
44 self.modality = modality
45 if children is None:
46 children = []
47 self.children = children
48
50 """
51 This node contains its own modality and the modalities in all
52 of its subtrees.
53 """
54 if self.modality == modality:
55
56 return True
57 else:
58
59 return self.generalizes(modality)
60
62 """
63 This node generalizes anothe modality if the other modality is
64 to be found in any of the nodes in its subtrees.
65 """
66 for child in self.children:
67 if child.contains(modality):
68 return True
69
70 return False
71
73 symbol = "%s" % self.modality
74 if symbol == "":
75 symbol = "NONE"
76 if len(self.children):
77 return "<%s: %s>" % (symbol,
78 ", ".join(["%s" % child for child in self.children]))
79 else:
80 return symbol
81
82 - def find(self, modality):
83 """
84 Returns a list of all the nodes in this tree (including this
85 node) with the given modality.
86 """
87 if self.modality == modality:
88 found = [self]
89 else:
90 found = []
91 found.extend(sum([child.find(modality) for child in self.children], []))
92 return found
93
94 @staticmethod
109
111 """
112 The tree is a DAG which defines a hierarchy of categories. If a
113 node Y is reachable from X, X generalizes Y. Modality Y can
114 therefore be used anywhere where an X modality is required, since
115 Y is a specialized type of X.
116
117 """
119 if root_nodes is None:
120 root_nodes = []
121 self.root_nodes = root_nodes
122
124 return reduce(lambda x,y: x and y, [child.contains(modality) for child in self.root_nodes])
125
127 return "<%s>" % ", ".join(["%s" % node for node in self.root_nodes])
128
129 - def accepts(self, modality_general, modality_specific):
130 """
131 Returns true if, under the modality hierarchy represented by the
132 tree, modality_specific can be accepted where a modality_general
133 is required. Equivalently, checks whether modality_specific is
134 a specialization of modality_general (including equality).
135 """
136 general_nodes = self.find(modality_general)
137
138 for node in general_nodes:
139 if node.contains(modality_specific):
140 return True
141
142 return False
143
144 - def find(self, modality):
145 """
146 Returns a list of all the nodes in this tree or subtrees with
147 the given modality.
148 """
149 return sum([child.find(modality) for child in self.root_nodes], [])
150
151 @staticmethod
153 """
154 Builds a modality tree from its DOM XML representation.
155 """
156 if xml.tagName != "modalities":
157 from jazzparser.grammar import GrammarReadError
158 raise GrammarReadError, "Tried to read modalities from a %s node" % xml.tagName
159 child_nodes = [node for node in xml.childNodes if node.nodeType == Node.ELEMENT_NODE and node.tagName == "modality"]
160 root_nodes = [ModalityTreeNode.from_dom(child) for child in child_nodes]
161 return ModalityTree(root_nodes)
162
164 """
165 A CCG slash class that wants modalities should inherit (first) from
166 the base Slash (or some subclass) and also from this, to add the
167 modality functionality.
168 """
170 if modality is None:
171 modality = ""
172 self.modality = modality
173
175 """
176 An additional requirement for equality.
177 """
178 return self.modality == other.modality
179
180 - def __post_string(self):
181 """
182 Add something to the end of the str to put the modality symbol on the slash.
183 If you want some alternative slash representation, you're
184 welcome to override this in the slash subclass.
185 """
186 return "%s " % self.modality
187 _post_string = property(__post_string)
188
191 _pre_string = property(__pre_string)
192
195 """
196 Look for the slash with id slash_id and set its modality.
197 """
198 if self.slash.id == slash_id:
199 self.slash.modality = modality
200 self.argument.set_slash_modality(slash_id, modality)
201 self.result.set_slash_modality(slash_id, modality)
202
206