Initial import
[jpf-core.git] / src / main / gov / nasa / jpf / util / event / EventConstructor.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18
19 package gov.nasa.jpf.util.event;
20
21 /**
22  * abstract class that hold API to create event trees
23  * 
24  * this factors out constructor methods so that they can be used inside of
25  * EventTrees and EventForests
26  */
27 public interface EventConstructor {
28
29   //--- overridable event factory method to facilitate creation of specialized event classes
30
31   default Event event (String name) {
32     return new Event(name, this);
33   }
34   
35   default Event event (String name, Object... arguments){
36     return new Event(name, arguments, this);
37   }
38
39   //--- compound constructors that create sets of events
40   
41   default Event alternatives (Event... events){
42     Event last = events[0];
43     for (int i = 1; i < events.length; i++) {
44       Event e = events[i];
45       last.setAlt(e);
46       last = e;
47     }
48     return events[0];
49   }
50
51   default Event sequence (Event... events) {
52     Event base = events[0];
53
54     for (int i = 1; i < events.length; i++) {
55       base.addNext(events[i]);
56     }
57     return base;
58   }
59
60   default Event iteration (int count, Event... events) {
61     Event seq = sequence(events);
62     Event[] it = new Event[count];
63
64     it[0] = seq;
65     for (int i=1; i<count; i++){
66       it[i] = seq.deepClone();
67     }
68
69     return sequence(it);
70   }
71
72   /**
73    * an alterative of all combinations of the specified events (regardless of order) 
74    */
75   default Event anyCombination (Event... events){
76     int n = events.length;
77     int max = 0;
78     for (int i=0; i<n; i++){
79       max = (max << 1) | 1;
80     }
81     
82     Event[] pathBuffer = new Event[n];
83     
84     // we use the no-event as the anchor
85     Event eFirst = new NoEvent();
86     
87     // now fill in all the remaining combinations
88     for (int i=1; i<=max; i++){
89       // init the path buffer
90       int pathLength=0;
91       for (int j=0, m=i; m != 0; j++){
92         if ((m & 1) != 0){
93           pathBuffer[pathLength++] = events[j];
94         }
95         m>>>=1;
96       }
97       
98       eFirst.addPath( pathLength, pathBuffer);
99     }
100       
101     return eFirst;
102   }
103   
104   
105   default void generatePermutation (int length, Event[] events, Event anchor, Event perm){
106     if (length == 0){
107       anchor.addAlternative(perm);
108       
109     } else {
110       outer:
111       for (Event e : events){
112         if (perm != null){
113           // check if e is already in there
114           for (Event ee = perm; ee != null; ee = ee.getNext()){
115             if (ee.equals(e)){
116               continue outer;
117             }
118           }          
119           e = perm.deepClone().addNext(e.deepClone());
120           
121         } else {
122           e = e.deepClone();
123         }
124         
125         generatePermutation( length-1, events, anchor, e);
126       }
127     }
128   }
129   
130   /**
131    * generate tree with all event permutations without repetitions.
132    * <2do> this is not particularly optimized
133    */
134   default Event anyPermutation (Event... events){
135     Event a = new NoEvent();
136     generatePermutation( events.length, events, a, null);
137     return a.getAlt();
138   }
139
140 }