Computer Laboratory

Transition.h
Go to the documentation of this file.
1 
2 /*
3  * Copyright (c) 2013 Jonathan Anderson
4  * All rights reserved.
5  *
6  * This software was developed by SRI International and the University of
7  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
8  * ("CTSRD"), as part of the DARPA CRASH research programme.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #ifndef TRANSITION_H
33 #define TRANSITION_H
34 
35 #include "Names.h"
36 #include "Protocol.h"
37 #include "Types.h"
38 
39 #include <llvm/ADT/ArrayRef.h>
40 #include <llvm/ADT/OwningPtr.h>
41 #include <llvm/ADT/SmallPtrSet.h>
42 #include <llvm/Support/Casting.h>
43 
44 #include <string>
45 
46 namespace tesla {
47 
48 // TESLA IR classes
49 class FieldAssignment;
50 class FunctionEvent;
51 class Identifier;
52 class Location;
53 class NowEvent;
54 
55 typedef llvm::MutableArrayRef<const Argument*> MutableReferenceVector;
56 
58 typedef llvm::SmallVector<Transition*,10> TransitionVector;
59 
61 typedef llvm::SmallPtrSet<const Transition*,4> TEquivalenceClass;
62 
64 typedef std::vector<TEquivalenceClass> TransitionSets;
65 
66 typedef llvm::SmallVector<llvm::SmallVector<Transition*, 16>, 4> TransitionVectors;
67 
69 class Transition {
70 public:
84  static void Create(State& From, State& To, TransitionVector& Transitions,
85  bool Init = false, bool Cleanup = false);
86 
100  static void Create(State& From, State& To, const FunctionEvent& Ev,
101  TransitionVector&, bool Init, bool Cleanup,
102  bool OutOfScope = false);
103 
117  static void Create(State& From, State& To, const FieldAssignment& A,
118  TransitionVector&, bool Init, bool Cleanup,
119  bool OutOfScope = false);
120 
121  static void Create(State& From, State& To, const NowEvent&,
123  bool Init, bool Cleanup);
124 
125  static void CreateSubAutomaton(State& From, State& To,
126  const Identifier&, TransitionVector&);
127 
131  static void Copy(State &From, State& To, const Transition* Other,
132  TransitionVector &, bool OutOfScope = false);
133 
135  static void GroupClasses(const TransitionVector&, TransitionSets&);
136 
137  virtual ~Transition() {}
138 
139  const State& Source() const { return From; }
140  const State& Destination() const { return To; }
141 
143  virtual bool EquivalentTo(const Transition &T) const = 0;
144 
146  bool RequiresInit() const { return Init; }
147 
149  bool RequiresCleanup() const { return Cleanup; }
150 
152  virtual bool IsStrict() const { return false; }
153 
155  virtual const ReferenceVector Arguments() const = 0;
156 
158  llvm::SmallVector<const Argument*,4> NewArguments() const;
159 
161  int NewArgMask() const;
162 
169  void ReferencesThusFar(llvm::OwningArrayPtr<const Argument*>& Args,
170  ReferenceVector& Ref) const;
171 
173  virtual bool IsRealisable() const = 0;
174 
176  virtual std::string ShortLabel() const = 0;
177 
179  virtual std::string DotLabel() const = 0;
180 
181  virtual std::string String() const;
182 
183  bool InScope() const { return !OutOfScope; }
184 
187  virtual TransitionKind getKind() const = 0;
188 
189 protected:
190  static void Register(llvm::OwningPtr<Transition>&, State& From, State& To,
192 
193  static void Append(const llvm::OwningPtr<Transition>&, TransitionSets&);
194 
195  Transition(const State& From, const State& To, bool Init, bool Cleanup,
196  bool OutOfScope)
197  : From(From), To(To), Init(Init), Cleanup(Cleanup),
198  OutOfScope(OutOfScope)
199  {
200  // An out-of-scope event cannot cause initialisation.
201  assert(!Init || !OutOfScope);
202  }
203 
204  const State& From;
205  const State& To;
206 
207  bool Init;
208  bool Cleanup;
209 
211  const bool OutOfScope;
212 };
213 
214 
216 class NullTransition : public Transition {
217 public:
218  bool IsRealisable() const { return false; }
219  std::string ShortLabel() const { return "ε"; }
220  std::string DotLabel() const { return "&#949;"; } // epsilon
221 
222  const ReferenceVector Arguments() const {
223  return ReferenceVector();
224  }
225 
226  bool EquivalentExpression(const Transition* Other) const {
227  return llvm::isa<NullTransition>(Other);
228  }
229 
230  static bool classof(const Transition *T) {
231  return T->getKind() == Null;
232  }
233  virtual TransitionKind getKind() const { return Null; };
234 
235 protected:
236  virtual bool EquivalentTo(const Transition &T) const {
237  return T.getKind() == Null;
238  }
239 
240 private:
241  NullTransition(const State& From, const State& To, bool Init, bool Cleanup)
242  : Transition(From, To, Init, Cleanup, false) {}
243 
244  friend class Transition;
245 };
246 
247 
249 class NowTransition : public Transition {
250 public:
251  bool IsRealisable() const { return true; }
252  std::string ShortLabel() const { return "NOW"; }
253  std::string DotLabel() const { return "NOW"; }
254 
255  const ReferenceVector Arguments() const { return Refs; }
256  const Location& Location() const { return Ev.location(); }
257 
258  bool EquivalentExpression(const Transition* Other) const {
259  auto *T = llvm::dyn_cast<NowTransition>(Other);
260  if (!T) return false;
261 
262  return T->Ev == Ev;
263  }
264 
265  static bool classof(const Transition *T) {
266  return T->getKind() == Now;
267  }
268  virtual TransitionKind getKind() const { return Now; };
269 
270 protected:
271  virtual bool EquivalentTo(const Transition &T) const {
272  return T.getKind() == Now;
273  }
274 
275 private:
276  NowTransition(const State& From, const State& To, const NowEvent& Ev,
277  const ReferenceVector& Refs, bool Init, bool Cleanup)
278  : Transition(From, To, Init, Cleanup, false), Ev(Ev), Refs(Refs)
279  {
280  }
281 
282  const NowEvent& Ev;
283  const ReferenceVector Refs;
284 
285  friend class Transition;
286 };
287 
288 
290 class FnTransition : public Transition {
291 public:
292  bool IsRealisable() const { return true; }
293  std::string ShortLabel() const;
294  std::string DotLabel() const;
295 
296  const FunctionEvent& FnEvent() const { return Ev; }
297  const ReferenceVector Arguments() const;
298  bool IsStrict() const { return Ev.strict(); }
299 
300  bool EquivalentExpression(const Transition* Other) const {
301  auto *T = llvm::dyn_cast<FnTransition>(Other);
302  if (!T) return false;
303 
304  return T->Ev == Ev;
305  }
306 
307  static bool classof(const Transition *T) {
308  return T->getKind() == Fn;
309  }
310 
311  virtual TransitionKind getKind() const { return Fn; };
312 
313 protected:
314  virtual bool EquivalentTo(const Transition &T) const {
315  return (T.getKind() == Fn) &&
316  (Ev == llvm::cast<FnTransition>(&T)->FnEvent());
317  }
318 
319 private:
320  FnTransition(const State& From, const State& To, const FunctionEvent& Ev,
321  bool Init, bool Cleanup, bool OutOfScope)
322  : Transition(From, To, Init, Cleanup, OutOfScope), Ev(Ev) {}
323 
324  const FunctionEvent& Ev;
325 
326  friend class Transition;
327 };
328 
329 
332 public:
333  bool IsRealisable() const { return true; }
334  std::string ShortLabel() const;
335  std::string DotLabel() const;
336 
337  const ReferenceVector Arguments() const { return Refs; }
338  const FieldAssignment& Assignment() const { return Assign; }
339  bool IsStrict() const { return Assign.strict(); }
340 
341  bool EquivalentExpression(const Transition* Other) const {
342  auto *T = llvm::dyn_cast<FieldAssignTransition>(Other);
343  if (!T) return false;
344 
345  return T->Assign == Assign;
346  }
347 
348  static bool classof(const Transition *T) {
349  return T->getKind() == FieldAssign;
350  }
351 
352  virtual TransitionKind getKind() const { return FieldAssign; };
353 
354 protected:
355  virtual bool EquivalentTo(const Transition &T) const {
356  return (T.getKind() == FieldAssign) &&
357  (Assign == llvm::cast<FieldAssignTransition>(&T)->Assignment());
358  }
359 
360 private:
361  FieldAssignTransition(const State& From, const State& To,
362  const FieldAssignment& A, bool Init, bool Cleanup,
363  bool OutOfScope);
364 
365  static const char *OpString(FieldAssignment::AssignType);
366 
367  const FieldAssignment& Assign;
368 
369  llvm::OwningArrayPtr<const Argument*> ReferencedVariables;
370  ReferenceVector Refs;
371 
372  friend class Transition;
373 };
374 
375 
378 public:
379  bool IsRealisable() const { return false; }
380  std::string ShortLabel() const { return ShortName(ID); }
381  std::string DotLabel() const { return ShortName(ID); }
382 
383  const ReferenceVector Arguments() const;
384  const Identifier& GetID() const { return ID; }
385 
386  bool EquivalentExpression(const Transition* Other) const {
387  auto *T = llvm::dyn_cast<SubAutomatonTransition>(Other);
388  if (!T) return false;
389 
390  return T->ID == ID;
391  }
392 
393  static bool classof(const Transition *T) {
394  return T->getKind() == SubAutomaton;
395  }
396 
397  virtual TransitionKind getKind() const { return SubAutomaton; };
398 
399 protected:
400  virtual bool EquivalentTo(const Transition &T) const {
401  return (T.getKind() == SubAutomaton) &&
402  (ID == llvm::cast<SubAutomatonTransition>(&T)->ID);
403  }
404 
405 private:
406  SubAutomatonTransition(const State& From, const State& To,
407  const Identifier& ID)
408  : Transition(From, To, false, false, false), ID(ID) {}
409 
410  const Identifier& ID;
411 
412  friend class Transition;
413 };
414 
415 
416 } // namespace tesla
417 
418 #endif // TRANSITION_H
419