1 """Temporal additions to basic lambda calculus semantics.
2
3 Many formalisms will store temporal information along with their
4 logical forms. This module provides the basic stuff that's needed
5 to add temporal information to a semantics.
6
7 Note that this is completely separate from the lambda calculus base
8 classes, so they may be used without temporal information.
9
10 """
11 """
12 ============================== License ========================================
13 Copyright (C) 2008, 2010-12 University of Edinburgh, Mark Granroth-Wilding
14
15 This file is part of The Jazz Parser.
16
17 The Jazz Parser is free software: you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation, either version 3 of the License, or
20 (at your option) any later version.
21
22 The Jazz Parser is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with The Jazz Parser. If not, see <http://www.gnu.org/licenses/>.
29
30 ============================ End license ======================================
31
32 """
33 __author__ = "Mark Granroth-Wilding <mark.granroth-wilding@ed.ac.uk>"
34
35 from jazzparser.data import Fraction
36 import copy, logging
37
38
39 logger = logging.getLogger("main_logger")
40
42 """
43 Adds temporal information to a logical form.
44 Logical form classes that want to store temporal information should
45 inherit from the approriate base logical form class and this.
46
47 Note that you must inherit from the logical form class as well:
48 just subclassing this may result in horrible things happening.
49 You should also call Temporal's init when initializing subclasses.
50 """
51 timed_object = False
52
53 - def __init__(self, duration=None, time=None):
58
60 """
61 Return a list of the time values of only predicates and tonal
62 denotations. The list is strictly in the sequential order
63 of the harmonic movements.
64
65 May be overridden by subclasses.
66
67 @note: this used to be an abstract method, which subclasses
68 were required to override. Since it is not used much (or at
69 all) in recent formalisms, it is no longer abstract and will
70 default to returning an empty list if not overridden.
71
72 """
73 return []
74
76 """
77 Returns a list of the time values of the constituents of the
78 logical form, including non-literal elements if they have times
79 (e.g. variables).
80
81 """
82 time_list = []
83 if self.timed_object:
84
85 time_list.append(self.time)
86
87 for child in self.get_children():
88
89 time_list.extend(child.get_time_list())
90 return time_list
91
93 """
94 Returns a list of times at which each point on the path occurs,
95 I{only} if the semantics represents a list of points, or
96 something that could be converted into one trivially.
97
98 @raise TemporalError: if the LF does not represent a
99 tonal space path.
100
101 """
102 raise TemporalError, "%s cannot provide tonal space path timings" % type(self).__name__
103
105 """
106 Recursively sets the time property on this and all children
107 that can accept a time value.
108
109 """
110 self.time = time
111 for child in self.get_children():
112 child.set_all_times(time)
113
118 duration = property(__get_duration, __set_duration)
119 """The duration of this phrase. Always None for types with timed_object=False."""
120
125 time = property(__get_time, __set_time)
126 """The onset time of this phrase. Always None for types with timed_object=False."""
127
129 """
130 Should be overridden by subclasses.
131
132 Sets the start time of this logical form. This is different to
133 just setting the time property: using set_time() may pass the
134 time property down to its children if that is appropriate for
135 the semantic type.
136
137 It is also distinct from set_all_times(),
138 which recursively sets the time on all children.
139
140 This must be provided by all subclasses.
141
142 """
143 raise NotImplementedError, "%s does not provide a set_time()" % type(self).__name__
144
146 """
147 Checks recursively that two logical forms, assumed equal,
148 have the same timings.
149 Note that it is important that this is only called when
150 self == other, or else bad things might happen.
151
152 """
153 return self.time != other.time and \
154 all(child1.simultaneous(child2) for (child1, child2) in zip(self.get_children(), other.get_children()))
155
182
184 """
185 A generic decorator to wrap any rule application to perform the
186 time assignment manipulation of the semantics.
187
188 @type semantics_only: bool
189 @param semantics_only: if True, assumes this is an apply_rule_semantics(),
190 so the results will be logical forms only (not signs)
191
192 """
193 def wrap(main_fun):
194 def apply_rule(self, cat_list, *args, **kwargs):
195
196 res = main_fun(self, cat_list, *args, **kwargs)
197 if res is not None:
198
199 if all(cat.semantics.duration is not None for cat in cat_list):
200 duration = sum(cat.semantics.duration for cat in cat_list)
201
202 for r in res:
203 if semantics_only:
204 r.duration = duration
205 else:
206 r.semantics.duration = duration
207 return res
208 return apply_rule
209 return wrap
210
211
212
213 temporal_comp_apply = temporal_rule_apply
214 """ @deprecated: use temporal_rule_apply """
215 temporal_app_apply = temporal_rule_apply
216 """ @deprecated: use temporal_rule_apply """
217
220
222 """
223 Simple utility to pick the earliest of a list of times (which
224 may include Nones).
225
226 Will return None if there are no times that aren't None.
227
228 """
229 notnones = [t for t in times if t is not None]
230 if len(notnones) == 0:
231 return None
232 return min(notnones)
233