Synthia
Generic and flexible data structure generator
Record.java
Go to the documentation of this file.
1 /*
2  Synthia, a data structure generator
3  Copyright (C) 2019-2021 Laboratoire d'informatique formelle
4  Université du Québec à Chicoutimi, Canada
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 package ca.uqac.lif.synthia.sequence;
20 
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 
25 import ca.uqac.lif.petitpoucet.NodeFactory;
26 import ca.uqac.lif.petitpoucet.Part;
27 import ca.uqac.lif.petitpoucet.PartNode;
28 import ca.uqac.lif.petitpoucet.function.ExplanationQueryable;
29 import ca.uqac.lif.synthia.Bounded;
30 import ca.uqac.lif.synthia.Picker;
33 
34 /**
35  * Picker that records and returns the values produced by another picker.
36  * This picker can be used in combination with {@link Playback} to
37  * reliably reproduce the behavior of another picker.
38  * <pre>
39  * RandomInteger ri = new RandomInteger(0, 10);
40  * Record&lt;Integer&gt; rec = new Record&lt;Integer&gt;(ri);
41  * System.out.println(rec.pick()); // 3
42  * System.out.println(rec.pick()); // 1
43  * System.out.println(rec.pick()); // 4
44  * List&lt;Integer&gt; values = rec.getValues(); // [3, 1, 4]
45  * </pre>
46  * @param <T> The type of objects to pick
47  * @ingroup API
48  */
49 public class Record<T> implements Picker<T>, ExplanationQueryable, SequenceShrinkable<T>
50 {
51  /**
52  * The picker that generates the values
53  */
54  /*@ non_null @*/ protected Picker<T> m_picker;
55 
56  /**
57  * The list of values produced by the picker so far
58  */
59  /*@ non_null @*/ protected List<T> m_values;
60 
61  /**
62  * Creates a new Record picker
63  * @param picker The picker that generates the values
64  */
65  public Record(/*@ non_null @*/ Picker<T> picker)
66  {
67  super();
68  m_picker = picker;
69  m_values = new ArrayList<>();
70  }
71 
72  private Record(Picker<T> picker, List<T> values)
73  {
74  m_picker = picker;
75  m_values = values;
76  }
77 
78  /**
79  * Clears the values recorded so far.
80  */
81  public void clear()
82  {
83  m_values.clear();
84  }
85 
86  /**
87  * Puts the Record picker back into its initial state. This means that the
88  * sequence of calls to {@link #pick()} will produce the same values
89  * as when the object was instantiated.
90  */
91  @Override
92  public void reset()
93  {
94  m_picker.reset();
95  m_values.clear();
96  }
97 
98 
99  /**
100  * Picks a value, records it and returns the value. Typically, this method is expected to return non-null
101  * objects; a <tt>null</tt> return value is used to signal that no more
102  * objects will be produced. That is, once this method returns
103  * <tt>null</tt>, it should normally return <tt>null</tt> on all subsequent
104  * calls.
105  * @return The value recorded from another picker.
106  */
107  @Override
108  public T pick()
109  {
110  T value = m_picker.pick();
111  m_values.add(value);
112  return value;
113  }
114 
115 
116  /**
117  * Creates a copy of the Record picker.
118  * @param with_state If set to <tt>false</tt>, the returned copy is set to
119  * the class' initial state (i.e. same thing as calling the picker's
120  * constructor). If set to <tt>true</tt>, the returned copy is put into the
121  * same internal state as the object it is copied from.
122  * @return The copy of the Record picker
123  */
124  @Override
125  /*@ pure non_null @*/ public Record<T> duplicate(boolean with_state)
126  {
127 
128  Record<T> copy = new Record<T>(m_picker.duplicate(with_state), new ArrayList<T>(m_values));
129  if (!with_state)
130  {
131  copy.m_values.clear();
132  }
133  return copy;
134  }
135 
136  /**
137  * Gets the number of values recorded by the picker so far
138  * @return The number of recorded values
139  */
140  /*@ pure @*/ public int getCount()
141  {
142  return m_values.size();
143  }
144 
145  @Override
146  public PartNode getExplanation(Part p)
147  {
148  return getExplanation(p, NodeFactory.getFactory());
149  }
150 
151  @Override
152  public PartNode getExplanation(Part p, NodeFactory f)
153  {
154  PartNode root = f.getPartNode(p, this);
155  int index = -1;
156  Part head = p.head();
157  if (head != null && head instanceof NthSuccessiveOutput)
158  {
159  index = ((NthSuccessiveOutput) head).getIndex();
160  }
161  if (index < 0 || index > m_values.size())
162  {
163  // Not a valid part, end there
164  return root;
165  }
166  root.addChild(f.getPartNode(p, m_picker));
167  return root;
168  }
169 
170  @Override
172  {
173  List<Integer> indices = new ArrayList<Integer>();
174  int num_to_pick = (int) (m * (float) m_values.size());
175  while (indices.size() < num_to_pick)
176  {
177  int index = (int) Math.floor(d.pick() * m_values.size());
178  if (!indices.contains(index))
179  {
180  indices.add(index);
181  }
182  }
183  Collections.sort(indices);
184  List<T> values = new ArrayList<T>(indices.size());
185  for (int index : indices)
186  {
187  values.add(m_values.get(index));
188  }
189  return new Playback<T>(values);
190  }
191 
192  @Override
193  public boolean isDone()
194  {
195  if (m_picker instanceof Bounded)
196  {
197  return ((Bounded<?>) m_picker).isDone();
198  }
199  return false;
200  }
201 
202  @Override
203  public List<T> getSequence()
204  {
205  return m_values;
206  }
207 }
ca.uqac.lif.synthia.Picker
Picks an object.
Definition: Picker.java:36
ca.uqac.lif.synthia.sequence.Record
Picker that records and returns the values produced by another picker.
Definition: Record.java:49
ca.uqac.lif.synthia.sequence.Record.duplicate
Record< T > duplicate(boolean with_state)
Creates a copy of the Record picker.
Definition: Record.java:125
ca.uqac.lif.synthia.sequence.Record.getExplanation
PartNode getExplanation(Part p, NodeFactory f)
Definition: Record.java:152
ca.uqac.lif.synthia.sequence.Record.shrink
SequenceShrinkable< T > shrink(Picker< Float > d, float m)
Shrinks a picker.
Definition: Record.java:171
ca.uqac.lif.synthia.sequence.Playback
Picker that returns values taken from a list.
Definition: Playback.java:61
ca.uqac.lif.synthia.SequenceShrinkable
Signals that a picker can shrink the sequence of values it has produced since its last reset.
Definition: SequenceShrinkable.java:47
ca.uqac
ca.uqac.lif.synthia
Definition: Bounded.java:19
ca.uqac.lif.synthia.sequence.Record.isDone
boolean isDone()
Signals if the picker enumerates all values from a set.
Definition: Record.java:193
ca.uqac.lif.synthia.explanation
Objects related to the explanation of results produced by pickers.
Definition: Explanation.java:19
ca.uqac.lif
ca.uqac.lif.synthia.sequence.Record.pick
T pick()
Picks a value, records it and returns the value.
Definition: Record.java:108
ca.uqac.lif.synthia.Bounded
Interface used to signal that a picker enumerates all values from a set.
Definition: Bounded.java:26
ca.uqac.lif.synthia.sequence.Record.clear
void clear()
Clears the values recorded so far.
Definition: Record.java:81
ca
ca.uqac.lif.synthia.Picker.pick
T pick()
Picks an object.
ca.uqac.lif.synthia.sequence.Record.getExplanation
PartNode getExplanation(Part p)
Definition: Record.java:146
ca.uqac.lif.synthia.sequence.Record.m_picker
Picker< T > m_picker
The picker that generates the values.
Definition: Record.java:54
ca.uqac.lif.synthia.sequence.Record.getSequence
List< T > getSequence()
Gets the sequence of values that the picker has produced so far.
Definition: Record.java:203
ca.uqac.lif.synthia.sequence.Record.reset
void reset()
Puts the Record picker back into its initial state.
Definition: Record.java:92
ca.uqac.lif.synthia.sequence.Record.Record
Record(Picker< T > picker)
Creates a new Record picker.
Definition: Record.java:65
ca.uqac.lif.synthia.explanation.NthSuccessiveOutput
A Part pointing to the n-th output produced by a picker since its last call to reset().
Definition: NthSuccessiveOutput.java:36
ca.uqac.lif.synthia.sequence.Record.m_values
List< T > m_values
The list of values produced by the picker so far.
Definition: Record.java:59
ca.uqac.lif.synthia.sequence.Record.getCount
int getCount()
Gets the number of values recorded by the picker so far.
Definition: Record.java:140