Package jazzparser :: Package formalisms :: Package base :: Package semantics :: Module temporal
[hide private]
[frames] | no frames]

Source Code for Module jazzparser.formalisms.base.semantics.temporal

  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  # Get the logger from the logging system 
 39  logger = logging.getLogger("main_logger") 
 40   
41 -class Temporal(object):
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):
54 # Only store these values on timed objects 55 if self.timed_object: 56 self._duration = duration 57 self._time = time
58
59 - def get_literal_time_list(self):
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
75 - def get_time_list(self):
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 # First find our own time 85 time_list.append(self.time) 86 87 for child in self.get_children(): 88 # Get a similar list from each child and join them all together 89 time_list.extend(child.get_time_list()) 90 return time_list
91
92 - def get_path_times(self):
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
104 - def set_all_times(self, time):
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
114 - def __get_duration(self):
115 return self._duration if self.timed_object else None
116 - def __set_duration(self,dur):
117 self._duration = dur if self.timed_object else None
118 duration = property(__get_duration, __set_duration) 119 """The duration of this phrase. Always None for types with timed_object=False.""" 120
121 - def __get_time(self):
122 return self._time if self.timed_object else None
123 - def __set_time(self, time):
124 self._time = time if self.timed_object else None
125 time = property(__get_time, __set_time) 126 """The onset time of this phrase. Always None for types with timed_object=False.""" 127
128 - def set_time(self, time):
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
145 - def simultaneous(self, other):
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
156 -class TemporalSemantics(object):
157 """ 158 Adds temporal semantics to the Semantics root class. 159 """
160 - def _get_duration(self):
161 return self.lf.duration
162 - def _set_duration(self, value):
163 self.lf.duration = value
164 duration = property(_get_duration, _set_duration) 165
166 - def get_time_list(self):
167 return self.lf.get_time_list()
168
169 - def set_all_times(self, time):
170 """@see: L{Temporal.set_all_times}""" 171 self.lf.set_all_times(time)
172
173 - def set_time(self, time):
174 """@see: L{Temporal.set_time}""" 175 self.lf.set_time(time)
176
177 - def get_path_times(self):
178 """ 179 @see: L{Temporal.get_path_times} 180 """ 181 return self.lf.get_path_times()
182
183 -def temporal_rule_apply(semantics_only=False):
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 # Now hand over to the main apply_rule function 196 res = main_fun(self, cat_list, *args, **kwargs) 197 if res is not None: 198 # Combine the durations of the inputs, if they exist 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 # Set the duration on the result(s) 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 # These old specific rule type decorators have now been replaced by a 212 # generic decorator 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
218 -class TempralError(Exception):
219 pass
220
221 -def earliest_time(times):
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