Edinburgh Speech Tools  2.4-release
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends Pages
EST_Item.h
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1998 */
6 /* All Rights Reserved. */
7 /* Permission is hereby granted, free of charge, to use and distribute */
8 /* this software and its documentation without restriction, including */
9 /* without limitation the rights to use, copy, modify, merge, publish, */
10 /* distribute, sublicense, and/or sell copies of this work, and to */
11 /* permit persons to whom this work is furnished to do so, subject to */
12 /* the following conditions: */
13 /* 1. The code must retain the above copyright notice, this list of */
14 /* conditions and the following disclaimer. */
15 /* 2. Any modifications must be clearly marked as such. */
16 /* 3. Original authors' names are not deleted. */
17 /* 4. The authors' names are not used to endorse or promote products */
18 /* derived from this software without specific prior written */
19 /* permission. */
20 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
21 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
22 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
23 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
24 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
25 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
26 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
27 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
28 /* THIS SOFTWARE. */
29 /* */
30 /*************************************************************************/
31 /* Author : Alan W Black */
32 /* Date : February 1998 */
33 /* --------------------------------------------------------------------- */
34 /* */
35 /* General class for representing linguistic information within a */
36 /* EST_Relation. This consists of two parts, the relation specific */
37 /* part and the information content part. The information content */
38 /* part may be shared between multiple EST_Items. */
39 /* */
40 /* This is typically used to represent things like words, phones but */
41 /* more abstract entities like NPs and nodes in metrical trees. */
42 /* */
43 /*************************************************************************/
44 #ifndef __EST_ITEM_H__
45 #define __EST_ITEM_H__
46 
47 #include "EST_String.h"
48 #include "EST_Features.h"
49 #include "ling_class/EST_Item_Content.h"
50 
51 typedef EST_Val (*EST_Item_featfunc)(EST_Item *s);
52 extern val_type val_type_featfunc;
53 const EST_Item_featfunc featfunc(const EST_Val &v);
54 EST_Val est_val(const EST_Item_featfunc f);
55 
56 class EST_Relation;
57 class ling_class_init;
58 
59 
60 /** A class for containing individual linguistic objects such as
61 words or phones.
62 
63 These contain two types of information. This first is specific to the
64 \Ref{EST_Relation} we are viewing this ling item from, the second part
65 consists of a set of features. These features may be shared by
66 instances of this ling item in different <link
67 linkend="est-relation">EST_Relation</link> within the same <link
68 linkend="est-utterance">EST_Utterances</link>
69 
70 The shared part of an <link linkend="est-item">EST_Item</link> is
71 represented by the class EST_Item_Content. It should not normally be
72 accessed by the general users as reverse links from the contents to
73 each of the EST_Items it is part of are held ensure the
74 integrity of the structures. Changing these without maintain the
75 appropriate links is unlikely to be stable.
76 
77 We believe this structure is the most efficient for the most natural
78 use we envisage. Traversal of the items ....
79 
80 */
81 
82 class EST_Item
83 {
84  private:
85  EST_Item_Content *p_contents;
86  EST_Relation *p_relation;
87  // In general (when we need it)
88  // EST_TKVL <EST_String, EST_Item *> arcs;
89  // but specifically
90  EST_Item *n;
91  EST_Item *p;
92  EST_Item *u;
93  EST_Item *d;
94 
95  void unref_contents();
96  void ref_contents();
97  void copy(const EST_Item &s);
98 
99  // Internal manipulation functions
100  // Get the daughters of node, removing reference to them
101  EST_Item *grab_daughters(void);
102  /* Get the contents, removing reference to them, this doesn't
103  delete the contents if this item is the only reference */
104  EST_Item_Content *grab_contents(void);
105 
106 protected:
107  static void class_init(void);
108 
109  public:
110  /**@name Constructor Functions */
111  //@{
112  /// Default constructor
113  EST_Item();
114  /// Copy constructor only makes reference to contents
115  EST_Item(const EST_Item &item);
116  /// Includes reference to relation
117  EST_Item(EST_Relation *rel);
118  /// Most common form of construction
119  EST_Item(EST_Relation *rel, EST_Item *si);
120  /// Deletes it and references to it in its contents
121  ~EST_Item();
122  //@}
123 
124 
125  /**@name Feature access functions.
126  These functions are wrap-around functions to the basic access
127  functions in the \Ref{EST_Features} class. In all these
128  functions, if the optional argument <parameter>m} is set to 1, an
129  error is thrown if the feature does not exist*/
130 
131  //@{
132  /** return the value of the feature <parameter>name</parameter>
133  cast as a float */
134  const float F(const EST_String &name) const {return f(name).Float();}
135 
136  /** return the value of the feature <parameter>name</parameter> cast
137  as a float, returning <parameter>def</parameter> if not found.*/
138  const float F(const EST_String &name,float def) const
139  {return f(name,def).Float();}
140 
141  /** return the value of the feature <parameter>name</parameter>
142  cast as a EST_String */
143  const EST_String S(const EST_String &name) const {return f(name).string();}
144 
145  /** return the value of the feature <parameter>name</parameter>
146  cast as a EST_String,
147  returning <parameter>def</parameter> if not found.
148  */
149  const EST_String S(const EST_String &name, const EST_String &def) const
150  {return f(name, def).string();}
151 
152  /** return the value of the feature <parameter>name</parameter>
153  cast as a int */
154  const int I(const EST_String &name) const {return f(name).Int();}
155 
156  /** return the value of the feature <parameter>name</parameter> cast as a int
157  returning <parameter>def</parameter> if not found.*/
158  const int I(const EST_String &name, int def) const
159  {return f(name, def).Int();}
160 
161  /** return the value of the feature <parameter>name</parameter>
162  cast as a EST_Features */
163  EST_Features &A(const EST_String &name) const {return *feats(f(name));}
164 
165  /** return the value of the feature <parameter>name</parameter>
166  cast as a EST_Features,
167  returning <parameter>def</parameter> if not found.
168  */
169  EST_Features &A(const EST_String &name,EST_Features &def) const
170  {EST_Features *ff = new EST_Features(def);
171  return *feats(f(name, est_val(ff)));}
172  //@}
173 
174  /**@name Feature setting functions.
175  A separate function is provided for each permissible value type
176  */
177  //@{
178  /** set feature <parameter>name</parameter> to <parameter>val</parameter> */
179  void set(const EST_String &name, int ival)
180  { EST_Val pv(ival);features().set_path(name, pv); }
181 
182  /** set feature <parameter>name</parameter> to <parameter>val</parameter> */
183  void set(const EST_String &name, float fval)
184  { EST_Val pv(fval); features().set_path(name,pv); }
185 
186  /** set feature <parameter>name</parameter> to <parameter>val</parameter> */
187  void set(const EST_String &name, double fval)
188  { EST_Val pv((float)fval);features().set_path(name,pv); }
189 
190  /** set feature <parameter>name</parameter> to <parameter>val</parameter> */
191  void set(const EST_String &name, const EST_String &sval)
192  { EST_Val pv(sval);features().set_path(name,pv); }
193 
194  /** set feature <parameter>name</parameter> to <parameter>val</parameter> */
195  void set(const EST_String &name, const char *cval)
196  { EST_Val pv(cval);features().set_path(name,pv); }
197 
198  /** set feature <parameter>name</parameter> to <parameter>val</parameter>,
199  a function registered in
200  the feature function list. */
201  void set_function(const EST_String &name, const EST_String &funcname)
202  { features().set_function(name,funcname); }
203 
204  /** set feature <parameter>name</parameter> to <parameter>f</parameter>,
205  a set of features, which is copied into the object.
206  */
207  void set(const EST_String &name, EST_Features &f)
208  { EST_Features *ff = new EST_Features(f);
209  features().set_path(name, est_val(ff)); }
210 
211  /** set feature <parameter>name</parameter> to <parameter>f</parameter>,
212  whose type is EST_Val.
213  */
214  void set_val(const EST_String &name, const EST_Val &sval)
215  { features().set_path(name,sval); }
216  //@}
217 
218  /**@name Utility feature functions
219  */
220  //@{
221  /** remove feature <parameter>name</parameter> */
222  void f_remove(const EST_String &name)
223  { features().remove(name); }
224 
225  /** find all the attributes whose values are functions, and
226  replace them with their evaluation. */
227  void evaluate_features();
228 
229  /** TRUE if feature is present, FALSE otherwise */
230  int f_present(const EST_String &name) const
231  {return features().present(name); }
232 
233  // Number of items (including this) until no next item.
234  int length() const;
235  //@}
236 
237  // get contents from item
238  EST_Item_Content *contents() const { return (this == 0) ? 0 : p_contents;}
239  // used by tree manipulation functions
240  void set_contents(EST_Item_Content *li);
241 
242  // These should be deleted.
243  // The item's name
244  const EST_String name() const
245  { return (this == 0) ? EST_String::Empty : f("name",0).string(); }
246 
247  // Set item's name
248  void set_name(const EST_String &name) const
249  { if (this != 0) p_contents->set_name(name); }
250 
251  // Shouldn't normally be needed, except for iteration
252  EST_Features &features() const { return p_contents->f; }
253 
254  const EST_Val f(const EST_String &name) const
255  {
256  EST_Val v;
257  if (this == 0)
258  {
259  EST_error("item is null so has no %s feature",(const char *)name);
260  }
261  else
262  {
263  for (v=p_contents->f.val_path(name);
264  v.type() == val_type_featfunc && featfunc(v) != NULL;
265  v=(featfunc(v))((EST_Item *)(void *)this));
266  if (v.type() == val_type_featfunc)
267  EST_error("NULL %s function",(const char *)name);
268  }
269  return v;
270  }
271 
272 #if 0
273  const EST_Val &f(const EST_String &name, const EST_Val &def) const
274  {
275  if (this == 0)
276  return def;
277  else
278  {
279  const EST_Val *v;
280  for (v=&(p_contents->f.val_path(name, def));
281  v->type() == val_type_featfunc && featfunc(*v) != NULL;
282  v=&(featfunc(*v))((EST_Item *)(void *)this));
283  if (v->type() == val_type_featfunc)
284  v = &def;
285  return *v;
286  }
287  }
288 #endif
289 
290  const EST_Val f(const EST_String &name, const EST_Val &def) const
291  {
292  if (this == 0)
293  return def;
294  else
295  {
296  EST_Val v;
297  for (v=p_contents->f.val_path(name, def);
298  v.type() == val_type_featfunc && featfunc(v) != NULL;
299  v=(featfunc(v))((EST_Item *)(void *)this));
300  if (v.type() == val_type_featfunc)
301  v = def;
302  return v;
303  }
304  }
305 
306  /**@name Cross relational access */
307  //@{
308 
309  /// View item from another relation (const char *) method
310  EST_Item *as_relation(const char *relname) const
311  { return (this == 0) ? 0 : p_contents->Relation(relname); }
312 
313  /// TRUE if this item is in named relation
314  int in_relation(const EST_String &relname) const
315  { return (this == 0) ? 0 : p_contents->in_relation(relname); }
316 
317  /// Access to the relation links
318  EST_TKVL<EST_String, EST_Val> &relations() {return p_contents->relations;}
319 
320  /// The relation name of this particular item
321  const EST_String &relation_name() const;
322 
323  /// The relation of this particular item
324  EST_Relation *relation(void) const
325  { return (this == 0) ? 0 : p_relation; }
326 
327  /// True if li is the same item ignoring its relation viewpoint
328  int same_item(const EST_Item *li) const
329  { return contents() && li->contents() && (contents() == li->contents()); }
330  //@}
331 
332  // The remaining functions should not be accessed, they are should be
333  // regarded as private member functions
334 
335  // Splice together a broken list.
336 
337  static void splice(EST_Item *a, EST_Item *b)
338  { if(a !=NULL) a->n = b; if (b != NULL) b->p=a; }
339 
340  // Internal traversal - nnot recommended - use relation traversal functions
341  //
342  EST_Item *next() const { return this == 0 ? 0 : n; }
343  //
344  EST_Item *prev() const { return this == 0 ? 0 : p; }
345  //
346  EST_Item *down() const { return this == 0 ? 0 : d; }
347  //
348  EST_Item *up() const { return this == 0 ? 0 : u; }
349  // Last item (most next) at this level
350  EST_Item *last() const;
351  // First item (most prev) at this level
352  EST_Item *first() const;
353  // Highest (most up)
354  EST_Item *top() const;
355  // Lowest (most down)
356  EST_Item *bottom() const;
357  // First item which has no down, within the descendants of this item
358  EST_Item *first_leaf() const;
359  // Next item which has no down, following above this item if necessary
360  EST_Item *next_leaf() const;
361  // Last item which has no down, following above this item if necessary
362  EST_Item *last_leaf() const;
363  // Next item in pre order (root, daughters, siblings)
364  EST_Item *next_item() const;
365 
366 
367  // Insert a new item after this, with li's contents
368  EST_Item *insert_after(EST_Item *li=0);
369  // Insert a new item before this, with li's contents
370  EST_Item *insert_before(EST_Item *li=0);
371  // Insert a new item below this, with li's contents (see tree methods)
372  EST_Item *insert_below(EST_Item *li=0);
373  // Insert a new item above this, with li's contents (see tree methods)
374  EST_Item *insert_above(EST_Item *li=0);
375 
376  // Append a new daughter to this, with li's contents
377  EST_Item *append_daughter(EST_Item *li=0);
378  // Prepend a new daughter to this, with li's contents
379  EST_Item *prepend_daughter(EST_Item *li=0);
380  // Insert a new parent above this, with li's contents
381  EST_Item *insert_parent(EST_Item *li=0);
382 
383  // Delete this item and all its occurrences in other relations
384  void unref_all();
385 
386  // Verification, double links are consistent (used after reading in)
387  int verify() const;
388 
389  friend int i_same_item(const EST_Item *l1,const EST_Item *l2);
390  friend int move_item(EST_Item *from, EST_Item *to);
391  friend int merge_item(EST_Item *from, EST_Item *to);
392  friend int move_sub_tree(EST_Item *from, EST_Item *to);
393  friend int exchange_sub_trees(EST_Item *from,EST_Item *to);
394 
395  EST_Item &operator=(const EST_Item &s);
396  friend ostream& operator << (ostream &s, const EST_Item &a);
397  friend bool operator !=(const EST_Item &a, const EST_Item &b)
398  { return !i_same_item(&a,&b); }
399  friend bool operator ==(const EST_Item &a, const EST_Item &b)
400  { return i_same_item(&a,&b); }
401 
402  friend class EST_Relation;
403  friend class ling_class_init;
404 };
405 
406 inline int i_same_item(const EST_Item *l1,const EST_Item *l2)
407 {
408  return l1->contents() && l2->contents() &&
409  (l1->contents() == l2->contents());
410 }
411 
412 
413 inline EST_Item *as(const EST_Item *n,const char *relname)
414  { return n->as_relation(relname); }
415 
416 // Relation structure functions
417 #include "ling_class/EST_Relation_list.h"
418 #include "ling_class/EST_Relation_tree.h"
419 #include "ling_class/EST_Relation_mls.h"
420 
421 inline EST_Item *next_item(const EST_Item *node)
422  { return node->next_item(); }
423 
424 void remove_item(EST_Item *l, const char *relname);
425 
426 void copy_node_tree(EST_Item *from, EST_Item *to);
427 void copy_node_tree_contents(EST_Item *from, EST_Item *to);
428 
429 void evaluate(EST_Item *a,EST_Features &f);
430 
431 
432 #include "ling_class/EST_FeatureFunctionPackage.h"
433 
434 // Feature function support
435 void EST_register_feature_function_package(const char *name, void (*init_fn)(EST_FeatureFunctionPackage &p));
436 
437 void register_featfunc(const EST_String &name, const EST_Item_featfunc func);
438 const EST_Item_featfunc get_featfunc(const EST_String &name,int must=0);
439 EST_String get_featname(const EST_Item_featfunc func);
440 
441 #define EST_register_feature_functions(PACKAGE) \
442  do { \
443  extern void register_ ## PACKAGE ## _feature_functions(EST_FeatureFunctionPackage &p); \
444  EST_register_feature_function_package( #PACKAGE , register_ ## PACKAGE ## _feature_functions); \
445  } while(0)
446 
447 
448 #endif