Hoa central
Borrowing.php
Go to the documentation of this file.
1 <?php
2 
38 
39 use Hoa\Math;
40 use Hoa\Praspel;
41 
50 class Borrowing extends Variable
51 {
57  const TYPE_OLD = 0;
58 
64  const TYPE_EXTERNAL = 1;
65 
71  protected $_type = null;
72 
78  protected $_variable = null;
79 
80 
81 
91  public function __construct(
92  $name,
93  $local,
94  Praspel\Model\Clause $clause = null
95  ) {
96  parent::__construct($name, $local, $clause);
97  $this->determineType();
98 
99  return;
100  }
101 
108  protected function determineType()
109  {
110  $name = $this->getName();
111 
112  if ('\old(' === substr($name, 0, 5)) {
113  $this->computeOld(substr($name, 5, -1));
114  } elseif (false !== strpos($name, '>', 2)) {
115  $this->computeDynamicResolution($name);
116  } else {
117  throw new Praspel\Exception\Model(
118  'Variable %s would be a borrowing one, but its type cannot ' .
119  'be determined.',
120  0,
121  $name
122  );
123  }
124 
125  return;
126  }
127 
135  protected function computeOld($name)
136  {
137  $clause = $this->getClause();
138  $this->_type = static::TYPE_OLD;
139  $parent = $clause->getParent();
140 
141  while (
142  false === $parent->clauseExists('requires') &&
143  null !== $parent = $parent->getParent()
144  );
145 
146  if (null === $parent ||
147  false === $parent->clauseExists('requires')) {
148  throw new Praspel\Exception\Model('No parent or no requires.', 1);
149  }
150 
151  $requires = $parent->getClause('requires');
152  $inScopeVariables = $requires->getInScopeVariables();
153 
154  if (!isset($inScopeVariables[$name])) {
155  throw new Praspel\Exception\Model(
156  'Variable %s does not exist, cannot get its old value ' .
157  '(in @%s).',
158  2,
159  [$name, $clause->getName()]
160  );
161  }
162 
163  $this->_variable = &$inScopeVariables[$name];
164 
165  return;
166  }
167 
175  protected function computeDynamicResolution($name)
176  {
177  $this->_type = static::TYPE_EXTERNAL;
178 
179  $clause = $this->getClause();
180  $parts = explode('->', $name);
181  $head = array_shift($parts);
182 
183  if ('this' !== $head) {
184  throw new Praspel\Exception\Model('Not yet implemented!');
185  }
186 
187  $registry = Praspel::getRegistry();
188  $root = $clause->getRoot();
189  $bindedClass = $root->getBindedClass();
190 
191  if (null === $bindedClass) {
192  throw new Praspel\Exception\Model(
193  'Cannot resolve the dynamic identifier %s; ' .
194  '%s::getBindedClass returned null.',
195  3,
196  [$name, get_class($root)]
197  );
198  }
199 
200  $attribute = array_shift($parts);
201  $id = $bindedClass . '::$' . $attribute;
202 
203  if (!isset($registry[$id])) {
204  throw new Praspel\Exception\Model(
205  'The contract identifier %s does not exist in the registry.',
206  4,
207  $name
208  );
209  }
210 
211  $entry = $registry[$id];
212 
213  if (false === $entry->clauseExists('invariant')) {
214  throw new Praspel\Exception\Model(
215  '%s is not declared with an @invariant clause.',
216  5,
217  $id
218  );
219  }
220 
221  $targetedClause = $entry->getClause('invariant');
222 
223  if (!isset($targetedClause[$attribute])) {
224  throw new Praspel\Exception\Model(
225  'The identifier %s does not exist.',
226  6,
227  $attribute
228  );
229  }
230 
231  $variable = $targetedClause[$attribute];
232  $this->_variable = $variable;
233 
234  return;
235  }
236 
242  public function getType()
243  {
244  return $this->_type;
245  }
246 
252  public function getBorrowedVariable()
253  {
254  return $this->_variable;
255  }
256 
266  public function __set($name, $value)
267  {
268  return $this->getBorrowedVariable()->__set($name, $value);
269  }
270 
271  /*
272  * Call the predicate() method on realistic domains.
273  *
274  * @access public
275  * @param mixed $q Sampled value.
276  * @return boolean
277  */
278  public function predicate($q = null)
279  {
280  return $this->getBorrowedVariable()->predicate($q);
281  }
282 
290  public function sample(Math\Sampler $sampler = null)
291  {
292  return $this->getBorrowedVariable()->sample($sampler);
293  }
294 
300  public function reset()
301  {
302  return $this->getBorrowedVariable()->reset();
303  }
304 
311  public function key($scalar)
312  {
313  return $this->getBorrowedVariable()->key($scalar);
314  }
315 
322  public function contains($scalar)
323  {
324  return $this->getBorrowedVariable()->contains($scalar);
325  }
326 
333  public function is()
334  {
335  throw new Praspel\Exception\Model('TODO');
336  }
337 
345  public function domainof($variable)
346  {
347  return $this->getBorrowedVariable()->domainof($variable);
348  }
349 
355  public function &getDomains()
356  {
357  return $this->getBorrowedVariable()->getDomains();
358  }
359 
365  public function &getHeld()
366  {
367  return $this->getBorrowedVariable()->getHeld();
368  }
369 
375  public function isLocal()
376  {
377  return $this->getBorrowedVariable()->isLocal();
378  }
379 
385  public function getConstraints()
386  {
387  return $this->getBorrowedVariable()->getConstraints();
388  }
389 }
static getRegistry()
Definition: Praspel.php:121
__construct($name, $local, Praspel\Model\Clause $clause=null)
Definition: Borrowing.php:91
sample(Math\Sampler $sampler=null)
Definition: Borrowing.php:290