DSPython  00.03.03 — 25 juin 2012
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Pages
combinator.py
Aller à la documentation de ce fichier.
1 #!/usr/bin/env python
2 # -*- coding: latin-1 -*-
3 ##\package DSPython.combinator Combinateurs
4 #
5 # Cf. \htmlonly <a href="http://www.opimedia.be/Bruno_Marchal/index.htm#Theo" target="_blank">
6 # <tt>http://www.opimedia.be/Bruno_Marchal/index.htm#Theo</tt></a>\endhtmlonly\n
7 # et \htmlonly <a href="http://fr.wikipedia.org/wiki/Logique_combinatoire" target="_blank">
8 # <tt>http://fr.wikipedia.org/wiki/Logique_combinatoire</tt></a>\endhtmlonly
9 # pour une présentation de la logique combinatoire.
10 
11 ##\file
12 # Combinateurs
13 #
14 # Cf. \htmlonly <a href="http://www.opimedia.be/Bruno_Marchal/index.htm#Theo" target="_blank">
15 # <tt>http://www.opimedia.be/Bruno_Marchal/index.htm#Theo</tt></a>\endhtmlonly\n
16 # et \htmlonly <a href="http://fr.wikipedia.org/wiki/Logique_combinatoire" target="_blank">
17 # <tt>http://fr.wikipedia.org/wiki/Logique_combinatoire</tt></a>\endhtmlonly
18 # pour une présentation de la logique combinatoire.
19 
20 # (c) Olivier Pirson --- DragonSoft
21 # http://www.opimedia.be/DS/
22 # Débuté le 1er juillet 2007
23 ####################################
24 from __future__ import print_function
25 
26 ## Date du dernier changement pour ce module
27 VERSION = 'combinator --- 2010 April 12'
28 
29 import collections, sys, types
30 
31 import DSPython
32 
33 
34 
35 # ###########
36 # Fonctions #
37 #############
38 ## Fonction pour la dynamique du combinateur atomique B : Bxyz... --> x(yz)...
39 def func_B(a, s, nb):
40  """Fonction pour la dynamique du combinateur atomique B : Bxyz... --> x(yz)...
41  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
42  si len(s) => 3 et ((nb == None) ou (nb > 0))
43  alors renvoie (Combinator(x_1, x_3, Combinator(x_2, x_3), x_4, ... , x_k)
44  1)
45  sinon renvoie (Combinator(a, x_1, x_2, x_3, x_4, ..., x_k),
46  0)
47  (Seul a est évalué, une seule fois, et pas les x_i)
48 
49  Pre: a: Atom
50  s: Iterable de Combinator
51  nb: None ou naturel
52 
53  Result: (Combinator, naturel)
54 
55  O() = ..."""
56  assert isinstance(a, Atom), (type(a), a)
57  assert isinstance(s, collections.Iterable), (type(s), s)
58  if __debug__:
59  for x in s:
60  assert isinstance(x, Combinator), (type(x), x, s)
61  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
62 
63  return ((Combinator(s[0],
64  Combinator(s[1], s[2]),
65  *s[3:]),
66  1) if (len(s) >= 3) and ((nb == None) or (nb > 0))
67  else (Combinator(a, *s),
68  0))
69 
70 
71 ## Fonction pour la dynamique du combinateur atomique C : Cxyz... --> xzy...
72 def func_C(a, s, nb):
73  """Fonction pour la dynamique du combinateur atomique C : Cxyz... --> xzy...
74  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
75  si len(s) => 3 et ((nb == None) ou (nb > 0))
76  alors renvoie (Combinator(x_1, x_3, Combinator(x_2, x_3), x_4, ... , x_k)
77  1)
78  sinon renvoie (Combinator(a, x_1, x_2, x_3, x_4, ..., x_k),
79  0)
80  (Seul a est évalué, une seule fois, et pas les x_i)
81 
82  Pre: a: Atom
83  s: Iterable de Combinator
84  nb: None ou naturel
85 
86  Result: (Combinator, naturel)
87 
88  O() = ..."""
89  assert isinstance(a, Atom), (type(a), a)
90  assert isinstance(s, collections.Iterable), (type(s), s)
91  if __debug__:
92  for x in s:
93  assert isinstance(x, Combinator), (type(x), x, s)
94  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
95 
96  return ((Combinator(s[0], s[2], s[1], *s[3:]),
97  1) if (len(s) >= 3) and ((nb == None) or (nb > 0))
98  else (Combinator(a, *s),
99  0))
100 
101 
102 ## Fonction pour une "dynamique constante" : a... --> a...
103 def func_const(a, s, nb):
104  """Fonction pour une "dynamique constante" : a... --> a...
105  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
106  renvoie (Combinator(a, x_1, x_2, x_3, x_4, ..., x_k),
107  0) quelque soit nb
108  (Seul a est évalué, une seule fois, et pas les x_i)
109 
110  Pre: a: Atom
111  s: Iterable de Combinator
112  nb: None ou naturel
113 
114  Result: (Combinator, naturel)
115 
116  O() = 1"""
117  assert isinstance(a, Atom), (type(a), a)
118  assert isinstance(s, collections.Iterable), (type(s), s)
119  if __debug__:
120  for x in s:
121  assert isinstance(x, Combinator), (type(x), x, s)
122  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
123 
124  return (Combinator(a, *s),
125  0)
126 
127 
128 ## Fonction pour la dynamique du combinateur atomique I : Ix... --> x...
129 def func_I(a, s, nb):
130  """Fonction pour la dynamique du combinateur atomique I : Ix... --> x...
131  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
132  si len(s) => 1 et ((nb == None) ou (nb > 0))
133  alors renvoie (Combinator(x_1, x_2, x_3, x_4, ..., x_k),
134  1)
135  sinon renvoie (Combinator(a, x_1, x_2, x_3, x_4, ... ,x_k),
136  0)
137  (Seul a est évalué, une seule fois, et pas les x_i)
138 
139  Pre: a: Atom
140  s: Iterable de Combinator
141  nb: None ou naturel
142 
143  Result: (Combinator, naturel)
144 
145  O() = ..."""
146  assert isinstance(a, Atom), (type(a), a)
147  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
148  if __debug__:
149  for x in s:
150  assert isinstance(x, Combinator), (type(x), x, s)
151  assert isinstance(s, collections.Iterable), (type(s), s)
152 
153  return ((Combinator(*s),
154  1) if (len(s) >= 1) and ((nb == None) or (nb > 0))
155  else (Combinator(a, *s),
156  0))
157 
158 
159 ## Fonction pour la dynamique du combinateur atomique K : Kxy... --> x...
160 def func_K(a, s, nb):
161  """Fonction pour la dynamique du combinateur atomique K : Kxy... --> x...
162  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
163  si len(s) => 2 et ((nb == None) ou (nb > 0))
164  alors renvoie (Combinator(x_1, x_3, x_4, ..., x_k),
165  1)
166  sinon renvoie (Combinator(a, x_1, x_2, x_3, x_4, ... ,x_k),
167  0)
168  (Seul a est évalué, une seule fois, et pas les x_i)
169 
170  Pre: a: Atom
171  s: Iterable de Combinator
172  nb: None ou naturel
173 
174  Result: (Combinator, naturel)
175 
176  O() = ..."""
177  assert isinstance(a, Atom), (type(a), a)
178  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
179  if __debug__:
180  for x in s:
181  assert isinstance(x, Combinator), (type(x), x, s)
182  assert isinstance(s, collections.Iterable), (type(s), s)
183 
184  return ((Combinator(s[0], *s[2:]),
185  1) if (len(s) >= 2) and ((nb == None) or (nb > 0))
186  else (Combinator(a, *s),
187  0))
188 
189 
190 ## Fonction pour la dynamique du combinateur atomique S : Sxyz... --> xz(yz)...
191 def func_S(a, s, nb):
192  """Fonction pour la dynamique du combinateur atomique S : Sxyz... --> xz(yz)...
193  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
194  si len(s) => 3 et ((nb == None) ou (nb > 0))
195  alors renvoie (Combinator(x_1, x_3, Combinator(x_2, x_3), x_4, ... , x_k)
196  1)
197  sinon renvoie (Combinator(a, x_1, x_2, x_3, x_4, ..., x_k),
198  0)
199  (Seul a est évalué, une seule fois, et pas les x_i)
200 
201  Pre: a: Atom
202  s: Iterable de Combinator
203  nb: None ou naturel
204 
205  Result: (Combinator, naturel)
206 
207  O() = ..."""
208  assert isinstance(a, Atom), (type(a), a)
209  assert isinstance(s, collections.Iterable), (type(s), s)
210  if __debug__:
211  for x in s:
212  assert isinstance(x, Combinator), (type(x), x, s)
213  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
214 
215  return ((Combinator(s[0],
216  s[2],
217  Combinator(s[1], s[2]),
218  *s[3:]),
219  1) if (len(s) >= 3) and ((nb == None) or (nb > 0))
220  else (Combinator(a, *s),
221  0))
222 
223 
224 ## Fonction pour la dynamique du combinateur atomique W : Wxy... --> xyy...
225 def func_W(a, s, nb):
226  """Fonction pour la dynamique du combinateur atomique W : Wxy... --> xyy...
227  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
228  si len(s) => 2 et ((nb == None) ou (nb > 0))
229  alors renvoie (Combinator(x_1, x_2, x_2, x_3, x_4, ..., x_k),
230  1)
231  sinon renvoie (Combinator(a, x_1, x_2, x_3, x_4, ... ,x_k),
232  0)
233  (Seul a est évalué, une seule fois, et pas les x_i)
234 
235  Pre: a: Atom
236  s: Iterable de Combinator
237  nb: None ou naturel
238 
239  Result: (Combinator, naturel)
240 
241  O() = ..."""
242  assert isinstance(a, Atom), (type(a), a)
243  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
244  if __debug__:
245  for x in s:
246  assert isinstance(x, Combinator), (type(x), x, s)
247  assert isinstance(s, collections.Iterable), (type(s), s)
248 
249  return ((Combinator(s[0], s[1], s[1], *s[2:]),
250  1) if (len(s) >= 2) and ((nb == None) or (nb > 0))
251  else (Combinator(a, *s),
252  0))
253 
254 
255 ## Fonction pour le remplacement de la "méta-variable" x
256 def func_x(a, s, nb):
257  """Fonction pour le remplacement de la "méta-variable" x
258  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
259  si var_x != None et ((nb == None) ou (nb > 0))
260  alors renvoie (Combinator(var_x, x_1, x_2, x_3, x_4, ..., x_k),
261  1)
262  sinon renvoie (Combinator(a, x_1, x_2, x_3, x_4, ... ,x_k),
263  0)
264  (Seul a est évalué, une seule fois, et pas les x_i)
265 
266  Pre: a: Atom
267  s: Iterable de Combinator
268  nb: None ou naturel
269 
270  Result: (Combinator, naturel)
271 
272  O() = 1"""
273  assert isinstance(a, Atom), (type(a), a)
274  assert isinstance(s, collections.Iterable), (type(s), s)
275  if __debug__:
276  for x in s:
277  assert isinstance(x, Combinator), (type(x), x, s)
278  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
279 
280  return ((Combinator(var_x, *s),
281  1) if (var_x != None) and ((nb == None) or (nb > 0))
282  else (Combinator(a, *s),
283  0))
284 
285 
286 ## Fonction pour le remplacement de la "méta-variable" y
287 def func_y(a, s, nb):
288  """Fonction pour le remplacement de la "méta-variable" y
289  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
290  si var_y != None et ((nb == None) ou (nb > 0))
291  alors renvoie (Combinator(var_y, x_1, x_2, x_3, x_4, ..., x_k),
292  1)
293  sinon renvoie (Combinator(a, x_1, x_2, x_3, x_4, ... ,x_k),
294  0)
295  (Seul a est évalué, une seule fois, et pas les x_i)
296 
297  Pre: a: Atom
298  s: Iterable de Combinator
299  nb: None ou naturel
300 
301  Result: (Combinator, naturel)
302 
303  O() = 1"""
304  assert isinstance(a, Atom), (type(a), a)
305  assert isinstance(s, collections.Iterable), (type(s), s)
306  if __debug__:
307  for x in s:
308  assert isinstance(x, Combinator), (type(x), x, s)
309  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
310 
311  return ((Combinator(var_y, *s),
312  1) if (var_y != None) and ((nb == None) or (nb > 0))
313  else (Combinator(a, *s),
314  0))
315 
316 
317 ## Fonction pour le remplacement de la "méta-variable" z
318 def func_z(a, s, nb):
319  """Fonction pour le remplacement de la "méta-variable" z
320  Pour s = [x_1, x_2, x_3, x_4, ..., x_k]
321  si var_z != None et ((nb == None) ou (nb > 0))
322  alors renvoie (Combinator(var_z, x_1, x_2, x_3, x_4, ..., x_k),
323  1)
324  sinon renvoie (Combinator(a, x_1, x_2, x_3, x_4, ... ,x_k),
325  0)
326  (Seul a est évalué, une seule fois, et pas les x_i)
327 
328  Pre: a: Atom
329  s: Iterable de Combinator
330  nb: None ou naturel
331 
332  Result: (Combinator, naturel)
333 
334  O() = 1"""
335  assert isinstance(a, Atom), (type(a), a)
336  assert isinstance(s, collections.Iterable), (type(s), s)
337  if __debug__:
338  for x in s:
339  assert isinstance(x, Combinator), (type(x), x, s)
340  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
341 
342  return ((Combinator(var_z, *s),
343  1) if (var_z != None) and ((nb == None) or (nb > 0))
344  else (Combinator(a, *s),
345  0))
346 
347 
348 
349 # #########
350 # Classes #
351 ###########
352 ## "Atome" pour les combinateurs
353 class Atom(collections.Hashable, collections.Callable):
354  """"Atome" pour les combinateurs"""
355 
356  ## Initialise l'atome
357  def __init__(self, s, f=func_const):
358  """Initialise l'atome
359 
360  Pre: s: string non vide composée de caractères alphanumériques ou '_',
361  f: fonction : (Atom, Combinator, None ou naturel a) -> (Combinator, naturel b)
362  tel a == None ou a >= b
363 
364  O() = 1"""
365  assert isinstance(s, str), (type(s), s)
366  assert s != '', s
367  if __debug__:
368  for c in s:
369  assert c.isalnum() or (c == '_'), (c, s)
370  assert isinstance(f, types.FunctionType), type(f)
371 
372  ## Fonction décrivant la dynamique de l'atome
373  self._f = f
374 
375  ## String représentant l'atome
376  self._s = s
377 
378 
379  ## Renvoie (l'évaluation du combinateur atomique suivi des combinateurs de args,
380  # nombre d'étapes effectuées)
381  def __call__(self, *args, **keywords):
382  """Renvoie (l'évaluation du combinateur atomique suivi des combinateurs de args,
383  nombre d'étapes effectuées)
384  En fait renvoie self.f()(self, args, nb) répétée jusqu'à épuisé nb
385  Si nb == None alors évalue tant que le combinateur atomique du début réagit
386  (! certains combinateurs peuvent ne jamais s'arrêter)
387  sinon évalue au plus nb étapes
388 
389  Pre: args: Iterable de Combinator
390  keywords: nb=None ou naturel
391 
392  Result: (Combinator, naturel)
393 
394  O() = ..."""
395  assert isinstance(args, collections.Iterable), (type(args), args)
396  if __debug__:
397  for x in args:
398  assert isinstance(x, Combinator), (type(x), x, args)
399  assert len(keywords) <= 1, (len(keywords), keywords)
400  assert (len(keywords) == 0) or ('nb' in keywords), keywords
401 
402  nb = (keywords['nb'] if 'nb' in keywords
403  else None)
404 
405  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
406 
407  x, nb_eval = self.f()(self, args, nb)
408  if nb_eval == 0: # L'atome n'a rien fait
409  return (x, 0)
410  if nb != None:
411  assert nb >= nb_eval, (nb, nb_eval)
412 
413  nb -= nb_eval
414 
415  while (nb == None) or (nb > 0):
416  x, nb_tmp = x[0].f()(x[0], x[1:], nb=nb)
417  if nb_tmp == 0: # L'atome n'a rien fait
418  return (x, nb_eval)
419  else: # L'atome a réagit
420  if nb != None:
421  assert nb >= nb_tmp, (nb, nb_tmp)
422 
423  nb -= nb_tmp
424  nb_eval += nb_tmp
425  return (x, nb_eval)
426 
427 
428  ## cmp(self, other)
429  def __cmp__(self, other):
430  """Renvoie
431  <0 si la représentation (string) de self < la représentation (string) de other,
432  0 si la représentation (string) de self == la représentation (string) de other,
433  >0 si la représentation (string) de self > la représentation (string) de other
434 
435  Result: Integral
436 
437  Exception: TypeError si other n'est pas un Atom
438 
439  O() = ..."""
440  if not isinstance(other, Atom):
441  raise TypeError
442 
443  return (cmp(self._s, other._s) if sys.version_info[0] < 3
444  else (self._s > other._s) - (self._s < other._s))
445 
446 
447  ## self == other ?
448  def __eq__(self, other):
449  """Renvoie True si other est un Atom qui a même représentation (string) que self,
450  False sinon
451  (Ne se préoccupe pas des fonctions associées aux dynamiques des atomes)
452 
453  Result: bool
454 
455  O() = ..."""
456  return isinstance(other, Atom) and (self._s == other._s)
457 
458 
459  ## self >= other ?
460  def __ge__(self, other):
461  """Renvoie True si la représentation (string) de self >= la représentation (string) de other
462  False sinon
463 
464  Result: bool
465 
466  Exception: TypeError si other n'est pas un Atom
467 
468  O() = ..."""
469  if not isinstance(other, Atom):
470  raise TypeError
471 
472  return self._s >= other._s
473 
474 
475  ## self > other ?
476  def __gt__(self, other):
477  """Renvoie True si la représentation (string) de self > la représentation (string) de other
478  False sinon
479 
480  Result: bool
481 
482  Exception: TypeError si other n'est pas un Atom
483 
484  O() = ..."""
485  if not isinstance(other, Atom):
486  raise TypeError
487 
488  return self._s > other._s
489 
490 
491  ## Hashcode de self
492  def __hash__(self):
493  """Renvoie le hashcode de self
494 
495  Result: naturel
496 
497  O() = ..."""
498  return hash(self._s)
499 
500 
501  ## self <= other ?
502  def __le__(self, other):
503  """Renvoie True si la représentation (string) de self <= la représentation (string) de other
504  False sinon
505 
506  Result: bool
507 
508  Exception: TypeError si other n'est pas un Atom
509 
510  O() = ..."""
511  if not isinstance(other, Atom):
512  raise TypeError
513 
514  return self._s <= other._s
515 
516 
517  ## self < other ?
518  def __lt__(self, other):
519  """Renvoie True si la représentation (string) de self < la représentation (string) de other
520  False sinon
521 
522  Result: bool
523 
524  Exception: TypeError si other n'est pas un Atom
525 
526  O() = ..."""
527  if not isinstance(other, Atom):
528  raise TypeError
529 
530  return self._s < other._s
531 
532 
533  ## self != other ?
534  def __ne__(self, other):
535  """Renvoie True si other n'est pas un Atom
536  ou n'a pas la même représentation (string) que self,
537  False sinon
538  (Ne se préoccupe pas des fonctions associées aux dynamiques des atomes)
539 
540  Result: bool
541 
542  O() = ..."""
543  return not isinstance(other, Atom) or (self._s != other._s)
544 
545 
546  ## Renvoie l'atome sous forme de string "Atom('...')"
547  def __repr__(self):
548  """Renvoie l'atome sous forme de string "Atom('...')"
549 
550  Result: string "Atom('...')"
551 
552  O() = ..."""
553  return ''.join(("Atom('", self._s, "')"))
554 
555 
556  ## Renvoie l'atome sous forme de string
557  def __str__(self):
558  """Renvoie l'atome sous forme de string
559 
560  Result: string
561 
562  O() = ..."""
563  return self._s
564 
565 
566  ## Renvoie la fonction correspondant à la dynamique de l'atome
567  def f(self):
568  """Renvoie la fonction correspondant à la dynamique de l'atome
569 
570  Result: fonction : (Atom, Combinator, None ou naturel) -> (Combinator, naturel)
571 
572  O() = 1"""
573  return self._f
574 
575 
576  ## Renvoie le nombre d'argument nécessaires pour déclencher l'atome
577  def nb_args(self, max=100):
578  """Renvoie le nombre d'argument nécessaires pour déclencher l'atome
579  Si max==None alors essaie avec de plus en plus d'arguments,
580  sans s'arrêter jusqu'à ce que l'atome déclenche
581  (ou sans jamais s'arrêter si l'atome ne déclenche jamais)
582  Si max est un naturel alors essaie avec au plus max arguments.
583  Si l'atome n'a pas déclenché alors renvoie None
584 
585  Pre: max: None ou naturel
586 
587  Result: naturel ou None
588 
589  O() = 1"""
590  assert (max == None) or DSPython.natural_is(max), (type(max), max)
591 
592  nb = 0
593  l = []
594  while (max == None) or (max >= nb):
595  if self(*l, nb=1)[1] > 0:
596  return nb
597  l.append(_COMB_CONST)
598  nb += 1
599  return None
600 
601 
602 
603 ## Combinateur
604 # (Sequence non vide dont le premier élément est un Atom et les suivants des Combinator)
605 class Combinator(collections.Sequence, collections.Hashable, collections.Callable):
606  """Combinateur
607  (Sequence non vide dont le premier élément est un Atom et les suivants des Combinator)"""
608 
609  ## Initialise le Combinator
610  def __init__(self, *seq):
611  """Initialise le Combinator
612 
613  Pre: seq: Sequence non vide de Combinator, Atom,
614  bool, naturel (selon le système spécifié par natural_sys)
615  ou string représentant un combinateur
616 
617  Exception: TypeError si l contient des string incorrectes
618 
619  O() = ..."""
620  assert isinstance(seq, collections.Sequence), (type(seq), seq)
621  assert len(seq) > 0
622 
623  # Premier élément
624  x = seq[0]
625  if not (isinstance(x, Combinator) or isinstance(x, Atom)):
626  if isinstance(x, bool):
627  x = (K if x
628  else KI)
629  elif DSPython.natural_is(x):
630  x = Combinator.n_to(x)
631  elif isinstance(x, str):
632  x = Combinator.str_to(x)
633  if x == None:
634  raise TypeError
635 
636  assert isinstance(x, Combinator) or isinstance(x, Atom), (type(x), x, seq)
637 
638  if isinstance(x, Combinator) and x.atomic_is():
639  x = x[0]
640  l = ([x] if isinstance(x, Atom)
641  else list(x))
642 
643  # Éléments suivants
644  for x in seq[1:]:
645  if isinstance(x, bool):
646  x = (K if x
647  else KI)
648  elif isinstance(x, str):
649  x = Combinator.str_to(x)
650  if x == None:
651  raise TypeError
652 
653  assert isinstance(x, Combinator) or isinstance(x, Atom), (type(x), x, seq)
654 
655  l.append(Combinator(x) if isinstance(x, Atom)
656  else x)
657 
658  self._seq = tuple(l)
659 
660 
661  ## self & other
662  def __and__(self, other):
663  """self & other (combinateur booléen et)
664  En fait renvoie Combinator(Band, self, other)
665 
666  Pre: other: Combinator ou bool
667 
668  Result: Combinator
669 
670  Exception: TypeError si other n'est pas un Combinator ou un bool
671 
672  O() = ..."""
673  if not (isinstance(other, Combinator) or isinstance(other, bool)):
674  raise TypeError
675 
676  return Combinator(Band, self, other)
677 
678 
679  ## Renvoie (le combinateur évalué, le nombre d'étapes réalisées)
680  def __call__(self, nb=None):
681  """Renvoie (le combinateur évalué,
682  le nombre d'étapes réalisées)
683  Si nb == None alors tente d'évaluer jusqu'au bout
684  (! certains combinateurs peuvent ne jamais s'arrêter)
685  sinon évalue au plus nb étapes
686 
687  Pre: nb: None ou naturel
688 
689  Result: (Combinator, naturel)
690 
691  O() = ..."""
692  assert (nb == None) or DSPython.natural_is(nb), (type(nb), nb)
693 
694  x, nb_eval = self[0](*self[1:], nb=nb) # évaluation du combinateur atomique du début
695  if nb != None:
696  assert nb >= nb_eval, (nb, nb_eval)
697 
698  nb -= nb_eval
699  if nb <= 0:
700  return (x, nb_eval)
701 
702  # Parcours de la liste de Combinator à partir du deuxième élément
703  # (le premier est un Atom qui ne réagit plus)
704  l = [x[0]]
705  for i in range(1, len(x)):
706  assert isinstance(x[i], Combinator), (type(x[i]), x[i])
707 
708  t, nb_tmp = x[i](nb=nb) # évaluation de l'élément intérieur x[i]
709  l.append(t)
710  nb_eval += nb_tmp
711  if nb != None:
712  assert nb >= nb_tmp, (nb, nb_tmp)
713 
714  nb -= nb_tmp
715  if nb <= 0:
716  i += 1
717  return ((Combinator(*(tuple(l) + x[i:])), nb_eval) if len(x) > i
718  else (Combinator(*l), nb_eval))
719  return (Combinator(*l), nb_eval)
720 
721 
722  ## cmp(self, other)
723  def __cmp__(self, other):
724  """Renvoie <0 si self < other
725  0 si self == other
726  >0 si self > other
727  Si len(self) < len(other) alors renvoie <0
728  Si len(self) > len(other) alors renvoie >0
729  Si len(self) == len(other) alors c'est les premiers éléments différents qui déterminent
730 
731  Result: Integral
732 
733  Exception: TypeError si other n'est pas un Combinator
734 
735  O() = ..."""
736  if not isinstance(other, Combinator):
737  raise TypeError
738 
739  i = cmp(len(self), len(other))
740  return (i if i != 0
741  else cmp(self._seq, other._seq))
742 
743 
744  ## item in self ?
745  def __contains__(self, item):
746  """Renvoie True si le combinateur self contient le combinateur atomique item,
747  False sinon
748 
749  Result: bool
750 
751  Exception: TypeError si item n'est pas un Atom ou un Combinator
752 
753  O() = ..."""
754  if not (isinstance(item, Atom) or isinstance(item, Combinator)):
755  raise TypeError
756  if isinstance(item, Combinator) and (not item.atomic_is()):
757  return NotImplemented
758 
759  if isinstance(item, Combinator):
760  item = item[0]
761 
762  if self[0] == item:
763  return True
764  else:
765  for x in self[1:]:
766  if item in x:
767  return True
768  return False
769 
770 
771  ## self == other ?
772  def __eq__(self, other):
773  """Renvoie True si other est un Combinator égal à self,
774  False sinon
775  (Ne se préoccupe pas de l'éventuelle équivalence (théorique) entre les combinateurs)
776 
777  Result: bool
778 
779  O() = ..."""
780  return (isinstance(other, Combinator)
781  and (self.atomic_is() == other.atomic_is())
782  and (self[0] == other[0])
783  and (self.atomic_is()
784  or (self[1:] == other[1:])))
785 
786 
787  ## self[key]
788  def __getitem__(self, key):
789  """self[key]
790 
791  O() = ..."""
792  return self._seq.__getitem__(key)
793 
794 
795  ## Hashcode de self
796  def __hash__(self):
797  """Renvoie le hashcode de self
798 
799  Result: naturel
800 
801  O() = ..."""
802  return hash(self._seq)
803 
804 
805  ## Nombre naturel correspondant à self
806  def __int__(self):
807  """Nombre naturel correspondant à self
808  (Selon le système spécifié par natural_sys : BARENDREGT ou CHURCH)
809 
810  Pre: self: Combinator correspondant à un nombre naturel dans le système spécifié
811 
812  Result: naturel
813 
814  O() = ..."""
815  assert (natural_sys == BARENDREGT) or (natural_sys == CHURCH), natural_sys
816 
817  if natural_sys == BARENDREGT:
818  x = I
819  succ = NBsucc
820  else:
821  x = KI
822  succ = NCsucc
823  n = 0
824  while self != x:
825  n += 1
826  x = Combinator(succ, x)
827 
828  assert len(self) >= len(x), (len(self), len(x), self, x)# sinon précondition non remplie
829 
830  return n
831 
832 
833  ## Renvoie la longueur du combinateur
834  def __len__(self):
835  """Renvoie la longueur du combinateur
836 
837  Result: naturel > 0
838 
839  O() = ..."""
840  return len(self._seq)
841 
842 
843  ## self != other ?
844  def __ne__(self, other):
845  """Renvoie True si other n'est pas un Combinator
846  ou n'est pas la même Combinator que self,
847  False sinon
848  (Ne se préoccupe pas de l'éventuelle équivalence (théorique) entre les combinateurs)
849  O() = ..."""
850  return not self.__eq__(other)
851 
852 
853  ## self == K ?
854  def __nonzero__(self):
855  """Renvoie True si self == K,
856  False sinon
857  (Ne se préoccupe pas de l'éventuelle équivalence (théorique) entre les combinateurs)
858 
859  Result: bool
860 
861  O() = ..."""
862  return self == K
863 
864 
865  ## self | other
866  def __or__(self, other):
867  """self | other (combinateur booléen ou inclusif)
868  En fait renvoie Combinator(Bor, self, other)
869 
870  Pre: other: Combinator ou bool
871 
872  Result: Combinator
873 
874  Exception: TypeError si other n'est pas un Combinator ou un bool
875 
876  O() = ..."""
877  if not (isinstance(other, Combinator) or isinstance(other, bool)):
878  raise TypeError
879 
880  return Combinator(Bor, self, other)
881 
882 
883  ## Renvoie le combinateur sous forme de string "Combinator('...')"
884  def __repr__(self):
885  """Renvoie le combinateur sous forme de string "Combinator('...')"
886 
887  Result: string "Combinator('...')"
888 
889  O() = 1"""
890  return ''.join(("Combinator('", str(self), "')"))
891 
892 
893  ## Renvoie le combinateur sous forme de string
894  def __str__(self, allparent=False, left='(', right=')', space=' '):
895  """Renvoie le combinateur sous forme de string.
896  Si allparent alors avec toutes les parenthèses,
897  sinon évite les parenthèses superflues.
898  left représente la parenthèse gauche et right la droite.
899  Les "morceaux" du combinateur sont séparés par space
900 
901  Pre: allparent: valeur booléenne
902  left: string
903  right: string
904  space: string
905 
906  Result: string
907 
908  O() = ..."""
909  assert isinstance(left, str), (type(left), left)
910  assert isinstance(right, str), (type(right), right)
911  assert isinstance(space, str), (type(space), space)
912  assert isinstance(self[0], Atom)
913 
914  if self.atomic_is(): # Atom
915  return str(self[0])
916  else: # (Combinator, Combinator)
917  l = [left*(len(self) - 1) + str(self[0]) if allparent
918  else str(self[0])]
919  for x in self[1:]:
920  assert isinstance(x, Combinator)
921 
922  s = x.__str__(allparent=allparent, left=left, right=right, space=space)
923  if (not allparent) and (not x.atomic_is()):
924  s = left + s
925  if allparent or (not x.atomic_is()):
926  s += right
927  l.append(''.join(s))
928  return space.join(l)
929 
930 
931  ## self ^ other
932  def __xor__(self, other):
933  """self ^ other (combinateur booléen ou exclusif)
934  En fait renvoie Combinator(Bxor, self, other)
935 
936  Pre: other: Combinator ou bool
937 
938  Result: Combinator
939 
940  Exception: TypeError si other n'est pas un Combinator ou un bool
941 
942  O() = ..."""
943  if not (isinstance(other, Combinator) or isinstance(other, bool)):
944  raise TypeError
945 
946  return NotImplemented
947 
948 
949  ## Renvoie True si le combinateur est atomique, False sinon
950  def atomic_is(self):
951  """Renvoie True si le combinateur est atomique,
952  False sinon
953 
954  Result: bool
955 
956  O() = ..."""
957  assert isinstance(self[0], Atom), (type(self[0]), self[0])
958 
959  return len(self) == 1
960 
961 
962  ## Non self
963  def bnot(self):
964  """Non self (combinateur négation booléenne)
965  En fait renvoie Combinator(Bnot, self)
966 
967  Result: Combinator
968 
969  O() = ..."""
970  return Combinator(Bnot, self)
971 
972 
973  ## Renvoie le combinateur dans lequel chaque Atom atom est remplacé par new
974  def change_atom(self, atom, new):
975  """Renvoie le combinateur dans lequel chaque Atom atom est remplacé par new
976 
977  Pre: atom: Atom
978  new: Combinator ou Atom
979 
980  Result: Combinator
981 
982  O() = ..."""
983  assert isinstance(atom, Atom), type(atom)
984  assert isinstance(new, Combinator) or isinstance(new, Atom), type(new)
985 
986  l = [new if self[0] == atom
987  else self[0]]
988  for x in self[1:]:
989  l.append(x.change_atom(atom, new))
990  return Combinator(*l)
991 
992 
993  ## Renvoie la profondeur du combinateur
994  def depth(self):
995  """Renvoie la profondeur du combinateur
996  == (profondeur de l'arbre binaire correspondant) - 1.
997  depth(combinateur atomique) == 0
998  depth(combinateur (a b)) == max(depth(a), depth(b)) + 1
999 
1000  Result: naturel
1001 
1002  O() = ..."""
1003  n = 0
1004  for x in self[1:]:
1005  n = max(n, x.depth()) + 1
1006  return n
1007 
1008 
1009  ## Renvoie le combinateur correspondant au nombre naturel n
1010  # selon le système spécifié par natural_sys
1011  @staticmethod
1012  def n_to(n):
1013  """ Renvoie le combinateur correspondant au nombre naturel n
1014  (Selon le système spécifié par natural_sys : BARENDREGT ou CHURCH)
1015 
1016  Pre: n: naturel
1017 
1018  Result: Combinator
1019 
1020  O() = ..."""
1021  assert (natural_sys == BARENDREGT) or (natural_sys == CHURCH), natural_sys
1022  assert DSPython.natural_is(n), type(n)
1023 
1024  return (Combinator.n_to_Barendregt(n) if natural_sys == BARENDREGT
1025  else Combinator.n_to_Church(n))
1026 
1027 
1028  ## Renvoie le combinateur correspondant au nombre naturel n de Barendregt
1029  @staticmethod
1031  """Renvoie le combinateur correspondant au nombre naturel n de Barendregt
1032 
1033  Pre: n: naturel
1034 
1035  Result: Combinator
1036 
1037  O() = ..."""
1038  assert DSPython.natural_is(n), type(n)
1039 
1040  c = I
1041  for i in range(n):
1042  c = Combinator(NBsucc, c)
1043  return c
1044 
1045 
1046  ## Renvoie le combinateur correspondant au nombre naturel n de Church
1047  @staticmethod
1048  def n_to_Church(n):
1049  """Renvoie le combinateur correspondant au nombre naturel n de Church
1050 
1051  Pre: n: naturel
1052 
1053  Result: Combinator
1054 
1055  O() = ..."""
1056  assert DSPython.natural_is(n), type(n)
1057 
1058  c = KI
1059  for i in range(n):
1060  c = Combinator(NCsucc, c)
1061  return c
1062 
1063 
1064  ## Renvoie le nombre de combinateurs atomiques composant le combinateur (sa taille)
1065  def nb_atom(self):
1066  """Renvoie le nombre de combinateurs atomiques composant le combinateur (sa taille)
1067  == nombre de feuilles de l'arbre binaire correspondant.
1068  nb_atom(combinateur atomique) == 1
1069  nb_atom(combinateur (a b)) == nb_atom(a) + nb_atom(b)
1070 
1071  Result: naturel
1072 
1073  O() = ..."""
1074  nb = 1
1075  for x in self[1:]:
1076  nb += x.nb_atom()
1077  return nb
1078 
1079 
1080  ## Combinateur stable
1081  def stable_is(self):
1082  """Renvoie True si le combinateur est stable (il ne déclenche plus),
1083  False sinon
1084 
1085  Result: bool
1086 
1087  O() = ..."""
1088  return self(nb=1)[1] == 0
1089 
1090 
1091  ## Renvoie le combinateur représenté par le string s
1092  @staticmethod
1093  def str_to(s):
1094  """Renvoie le combinateur représenté par le string s
1095  (Si s n'est pas une réprésentation correcte alors renvoie None)
1096  Un string correcte est un string non vide
1097  comprenant des string appartenant à str_combs et des '(' et ')',
1098  le tout bien agencé
1099 
1100  Pre: s: string
1101 
1102  Result: Combinator ou None
1103 
1104  O() = ..."""
1105  assert isinstance(s, str), (type(s), s)
1106 
1107  if s == '':
1108  raise None
1109 
1110  l = [] # liste des Combinator déjà traités
1111  i = 0 # position courante dans le string s
1112  k = 0 # position dans le string s du départ de la sous-chaîne courante
1113  while i < len(s):
1114  if (s[i] == ' ') or (s[i] == '('): # caractère de séparation ' ' ou '('
1115  if i > k: # si il y a quelque chose à ajouté avant de passer au '(...)'
1116  if s[k:i] in str_combs:
1117  x = str_combs[s[k:i]]
1118 
1119  assert x != None
1120  else:
1121  return None
1122  l.append(Combinator(x))
1123  k = i + 1
1124 
1125  if s[i] == '(': # ouverture d'une '(...)'
1126  nb = 1
1127  while k < len(s): # parcourt jusqu'à trouvé le ')' qui correspond à cet '('
1128  if s[k] == '(':
1129  nb += 1
1130  elif s[k] == ')':
1131  nb -= 1
1132  if nb == 0:
1133  break
1134  k += 1
1135  if nb > 0: # pas trouvé le ')' correspondant
1136  return None
1137 
1138  comb = Combinator.str_to(s[i + 1:k]) # convertit la sous-chaîne '(...)'
1139  if comb != None:
1140  l.append(comb)
1141  i = k
1142  k += 1
1143  elif (s[i] != '_') and (not s[i].isalnum()): # caractère non valide (ou mal placé)
1144  return None
1145  i += 1
1146 
1147  if len(s) > k:
1148  if s[k:] in str_combs:
1149  x = str_combs[s[k:]]
1150 
1151  assert x != None
1152  else:
1153  return None
1154  l.append(Combinator(x))
1155 
1156  return (Combinator(*l) if l != [] else
1157  None)
1158 
1159 
1160 
1161 # ############
1162 # Constantes #
1163 ##############
1164 ## Constante pour utiliser les opérations sur les nombres naturels de Barendregt
1165 BARENDREGT = 1
1166 
1167 ## Constante pour utiliser les opérations sur les nombres naturels de Church
1168 CHURCH = 2
1169 
1170 
1171 ## Constante d'un atome de "dynamique constante", utilisée en interne
1172 _ATOM_CONST = Atom('c')
1173 
1174 
1175 ## Atome K (constante, à ne pas modifier)
1176 Atom_K = Atom('K', func_K)
1177 
1178 ## Atome S (constante, à ne pas modifier)
1179 Atom_S = Atom('S', func_S)
1180 
1181 
1182 ## Atome utilisé par la "méta-variable" x (constante, à ne pas modifier)
1183 Atom_Vx = Atom('x', func_x)
1184 
1185 ## Atome utilisé par la "méta-variable" y (constante, à ne pas modifier)
1186 Atom_Vy = Atom('y', func_y)
1187 
1188 ## Atome utilisé par la "méta-variable" z (constante, à ne pas modifier)
1189 Atom_Vz = Atom('z', func_z)
1190 
1191 
1192 
1193 # Combinateurs atomiques
1194 
1195 ## Constante d'un combinateur de "dynamique constante", utilisée en interne
1196 _COMB_CONST = Combinator(_ATOM_CONST)
1197 
1198 
1199 ## Combinateur K = combinateur vrai (constante, à ne pas modifier)
1200 K = Combinator(Atom_K)
1201 assert isinstance(K, Combinator)
1202 assert len(K) == 1, (len(K), K)
1203 assert K.atomic_is()
1204 assert isinstance(K[0], Atom)
1205 
1206 
1207 ## Combinateur S (constante, à ne pas modifier)
1208 S = Combinator(Atom_S)
1209 assert isinstance(S, Combinator)
1210 assert len(S) == 1, (len(S), S)
1211 assert S.atomic_is()
1212 assert isinstance(S[0], Atom)
1213 
1214 
1215 
1216 # Combinateurs standards
1217 
1218 ## Combinateur KK (constante, à ne pas modifier)
1219 KK = Combinator(K, K)
1220 assert isinstance(KK, Combinator)
1221 assert len(KK) == 2, (len(KK), KK)
1222 assert not KK.atomic_is()
1223 assert isinstance(KK[0], Atom)
1224 assert isinstance(KK[1], Combinator)
1225 
1226 
1227 ## Combinateur KS (constante, à ne pas modifier)
1228 KS = Combinator(K, S)
1229 assert isinstance(KS, Combinator)
1230 assert len(KS) == 2, (len(KS), KS)
1231 assert not KS.atomic_is()
1232 assert isinstance(KS[0], Atom)
1233 assert isinstance(KS[1], Combinator)
1234 
1235 
1236 ## Combinateur SS (constante, à ne pas modifier)
1237 SS = Combinator(S, S)
1238 
1239 
1240 ## Combinateur SK (constante, à ne pas modifier)
1241 SK = Combinator(S, K)
1242 
1243 
1244 ## Combinateur B = S(KS)K = combinateur produit pour les nombres naturels de Church
1245 # (constante, à ne pas modifier)
1246 B = Combinator(S, KS, K)
1247 
1248 
1249 ## Combinateur C = S[S(KB)S](KK) (constante, à ne pas modifier)
1251  Combinator(S,
1252  Combinator(K, B),
1253  S),
1254  KK)
1255 
1256 ## Combinateur I = SKK = combinateur nombre naturel 0 de Barendregt
1257 # (constante, à ne pas modifier)
1258 I = Combinator(SK, K)
1259 
1260 
1261 ## Combinateur O = SI (constante, à ne pas modifier)
1262 O = Combinator(S, I)
1263 
1264 
1265 ## Combinateur iota \htmlonly &iota;\endhtmlonly = S[O(KS)](KK) (constante, à ne pas modifier)
1266 iota = Combinator(S,
1267  Combinator(O, KS),
1268  KK)
1269 
1270 
1271 ## Combinateur KI = combinateur faux = combinateur nombre naturel 0 de Church
1272 # (constante, à ne pas modifier)
1273 KI = Combinator(K, I)
1274 
1275 
1276 ## Combinateur M = OI (constante, à ne pas modifier)
1277 M = Combinator(O, I)
1278 
1279 
1280 ## Combinateur L = SB(KM) (constante, à ne pas modifier)
1282  B,
1283  Combinator(K, M))
1284 
1285 
1286 ## Combinateur Omega \htmlonly &Omega;\endhtmlonly = MM (constante, à ne pas modifier)
1287 Omega = Combinator(M, M)
1288 
1289 
1290 ## Combinateur R = S(KB){S(KO)K} (constante, à ne pas modifier)
1292  Combinator(K, B),
1293  Combinator(S,
1294  Combinator(K, O),
1295  K))
1296 
1297 
1298 ## Combinateur T = S(K0)K (constante, à ne pas modifier)
1300  Combinator(K, O),
1301  K)
1302 
1303 
1304 ## Combinateur U = S(KO)M (constante, à ne pas modifier)
1306  Combinator(K, O),
1307  M)
1308 
1309 
1310 ## Combinateur V = S(KC)T (constante, à ne pas modifier)
1312  Combinator(K, C),
1313  T)
1314 
1315 
1316 ## Combinateur W = SS(KI) (constante, à ne pas modifier)
1317 W = Combinator(SS,
1318  Combinator(K, I))
1319 
1320 
1321 ## Combinateur Y = S(KM)[SB(KM)] (constante, à ne pas modifier)
1323  Combinator(K, M),
1324  Combinator(S,
1325  B,
1326  Combinator(K, M)))
1327 
1328 
1329 
1330 # Combinateurs booléens
1331 
1332 ## Combinateur not (négation booléenne) = S{O[K(KI)]}(KK) (constante, à ne pas modifier)
1333 Bnot = Combinator(S,
1334  Combinator(O,
1335  Combinator(K, KI)),
1336  KK)
1337 
1338 ## Autre combinateur not (négation booléenne) = S{O[O(KI)]}(KK) (constante, à ne pas modifier)
1339 Bnot_my = Combinator(S,
1340  Combinator(O,
1341  Combinator(O, KI)),
1342  KK)
1343 
1344 ## Combinateur and (et booléen, conjonction) = S(K{O[K(KI)]}) (constante, à ne pas modifier)
1345 Band = Combinator(S,
1346  Combinator(K,
1347  Combinator(O,
1348  Combinator(K, KI))))
1349 
1350 ## Combinateur or (ou booléen, disjonction) = O(KK) (constante, à ne pas modifier)
1351 Bor = Combinator(O, KK)
1352 
1353 ## Combinateur implication booléenne = S{K[O(KK)]} (constante, à ne pas modifier)
1354 Bimp = Combinator(S,
1355  Combinator(K,
1356  Combinator(O, KK)))
1357 
1358 ## Combinateur négation de la réciproque booléenne = O[K(KI)] (constante, à ne pas modifier)
1359 Bnotrec = Combinator(O,
1360  Combinator(K, KI))
1361 
1362 
1363 
1364 # Combinateurs nombres naturels de Barendregt
1365 
1366 ## Combinateur est égal à 0 ? pour nombres naturels de Barendregt = TK
1367 # (constante, à ne pas modifier)
1368 NBzero_is = Combinator(T, K)
1369 
1370 ## Combinateur successeur pour nombres naturels de Barendregt = V(KI)
1371 # (constante, à ne pas modifier)
1372 NBsucc = Combinator(V, KI)
1373 
1374 ## Combinateur prédécesseur pour nombres naturels de Barendregt = T(KI)
1375 # (constante, à ne pas modifier)
1376 NBprev = Combinator(T, KI)
1377 
1378 ## Combinateur prédécesseur pour nombres naturels de Barendregt = ???
1379 # (constante, à ne pas modifier)
1380 NBadd = Combinator(Y,
1381  Combinator(B,
1382  Combinator(S,
1383  Combinator(B,
1384  S,
1385  Combinator(C, NBzero_is))),
1386  Combinator(B,
1387  Combinator(B,
1388  Combinator(B, NBsucc)),
1389  Combinator(C,
1390  Combinator(B, C,
1391  Combinator(B, B)),
1392  NBprev))))
1393 
1394 
1395 
1396 # Combinateurs nombres naturels de Church
1397 
1398 ## Combinateur successeur pour les nombres naturels de Church = SB (constante, à ne pas modifier)
1399 NCsucc = Combinator(S, B)
1400 
1401 ## Combinateur addition pour les nombres naturels de Church = BS(BB)
1402 # (constante, à ne pas modifier)
1403 NCadd = Combinator(B,
1404  S,
1405  Combinator(B, B))
1406 
1407 
1408 ## Combinateur atomiques utilisé comme "méta-variable" x
1409 Vx = Combinator(Atom_Vx)
1410 
1411 ## Combinateur atomiques utilisé comme "méta-variable" y
1412 Vy = Combinator(Atom_Vy)
1413 
1414 ## Combinateur atomiques utilisé comme "méta-variable" z
1415 Vz = Combinator(Atom_Vz)
1416 
1417 
1418 
1419 # ###########
1420 # Variables #
1421 #############
1422 ## Spécifie le type de nombres naturels gérés par les opérations arithmétiques de la classe
1423 # == BARENDREGT ou CHURCH
1424 natural_sys = CHURCH
1425 
1426 
1427 ## Dictionnaire des strings reconnues comme combinateurs par str_to, associées à leur Combinator
1428 str_combs = {'K' : K,
1429  'S' : S,
1430  'x' : Vx,
1431  'y' : Vy,
1432  'z' : Vz}
1433 
1434 
1435 ## None ou Combinator qui remplacera la "méta-variable" Vx
1436 var_x = None
1437 
1438 ## None ou Combinator qui remplacera la "méta-variable" Vy
1439 var_y = None
1440 
1441 ## None ou Combinator qui remplacera la "méta-variable" Vz
1442 var_z = None
1443 
1444 
1445 
1446 # ######\cond MAINTEST
1447 # Main #
1448 ########
1449 if __name__ == '__main__':
1450  def main_test():
1451  """Test du module"""
1452  global natural_sys
1453 
1454  import sys
1455 
1456  try:
1457  if not 'profile' in dir():
1458  import psyco
1459  psyco.full()
1460  except ImportError:
1461  pass
1462 
1463  import DSPython.debug as debug
1464 
1465  debug.test_begin(VERSION, __debug__)
1466 
1467  BASICS = (K, S, KK, KS, SS, SK)
1468  STDS = (B, C, I, iota, KI, L, M, O, R, T, U, V, W, Y)
1469  BOOLS = (Bnot, Bnot_my, Band, Bor, Bimp, Bnotrec)
1470  NATURALS_FCT = (NBzero_is, NBsucc, NBprev, NBadd)
1471  NATURALS_FCT_CHURCH = (NCsucc, NCadd)
1472 
1473  STABLES = BASICS + STDS + BOOLS + (NCsucc, )
1474  UNSTABLES = (Omega, ) + NATURALS_FCT + (NCadd, )
1475 
1476  ALLS = STABLES + UNSTABLES
1477  VARS = (Vx, Vy, Vz)
1478 
1479  ALLS_VARS = ALLS + VARS
1480 
1481 
1482 
1483  print('func_B()...', end=''); sys.stdout.flush()
1484  assert func_B(Atom_K, (), 0) == (Combinator(Atom_K), 0)
1485  assert func_B(Atom_K, (), 1) == (Combinator(Atom_K), 0)
1486  assert func_B(Atom_K, (), 2) == (Combinator(Atom_K), 0)
1487  assert func_B(Atom_K, (), None) == (Combinator(Atom_K), 0)
1488 
1489  assert func_B(Atom_S, (), 0) == (Combinator(Atom_S), 0)
1490  assert func_B(Atom_S, (), 1) == (Combinator(Atom_S), 0)
1491  assert func_B(Atom_S, (), 2) == (Combinator(Atom_S), 0)
1492  assert func_B(Atom_S, (), None) == (Combinator(Atom_S), 0)
1493 
1494  assert func_B(Atom_K, (Vx, ), 0) == (Combinator(Atom_K, Vx), 0)
1495  assert func_B(Atom_K, (Vx, ), 1) == (Combinator(Atom_K, Vx), 0)
1496  assert func_B(Atom_K, (Vx, ), 2) == (Combinator(Atom_K, Vx), 0)
1497  assert func_B(Atom_K, (Vx, ), None) == (Combinator(Atom_K, Vx), 0)
1498 
1499  assert func_B(Atom_S, (Vx, ), 0) == (Combinator(Atom_S, Vx), 0)
1500  assert func_B(Atom_S, (Vx, ), 1) == (Combinator(Atom_S, Vx), 0)
1501  assert func_B(Atom_S, (Vx, ), 2) == (Combinator(Atom_S, Vx), 0)
1502  assert func_B(Atom_S, (Vx, ), None) == (Combinator(Atom_S, Vx), 0)
1503 
1504  assert func_B(Atom_K, (Vx, Vy), 0) == (Combinator(Atom_K, Vx, Vy), 0)
1505  assert func_B(Atom_K, (Vx, Vy), 1) == (Combinator(Atom_K, Vx, Vy), 0)
1506  assert func_B(Atom_K, (Vx, Vy), 2) == (Combinator(Atom_K, Vx, Vy), 0)
1507  assert func_B(Atom_K, (Vx, Vy), None) == (Combinator(Atom_K, Vx, Vy), 0)
1508 
1509  assert func_B(Atom_S, (Vx, Vy), 0) == (Combinator(Atom_S, Vx, Vy), 0)
1510  assert func_B(Atom_S, (Vx, Vy), 1) == (Combinator(Atom_S, Vx, Vy), 0)
1511  assert func_B(Atom_S, (Vx, Vy), 2) == (Combinator(Atom_S, Vx, Vy), 0)
1512  assert func_B(Atom_S, (Vx, Vy), None) == (Combinator(Atom_S, Vx, Vy), 0)
1513 
1514  for i in range(3, len(ALLS_VARS)):
1515  assert func_B(Atom_K, ALLS_VARS[:i], 0) == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1516  assert func_B(Atom_K, ALLS_VARS[:i], 1) == (Combinator(ALLS_VARS[0],
1517  Combinator(ALLS_VARS[1],
1518  ALLS_VARS[2]),
1519  *ALLS_VARS[3:i]), 1)
1520  assert func_B(Atom_K, ALLS_VARS[:i], 2) == (Combinator(ALLS_VARS[0],
1521  Combinator(ALLS_VARS[1],
1522  ALLS_VARS[2]),
1523  *ALLS_VARS[3:i]), 1)
1524  assert func_B(Atom_K, ALLS_VARS[:i], None) == (Combinator(ALLS_VARS[0],
1525  Combinator(ALLS_VARS[1],
1526  ALLS_VARS[2]),
1527  *ALLS_VARS[3:i]), 1)
1528 
1529  assert func_B(Atom_S, ALLS_VARS[:i], 0) == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1530  assert func_B(Atom_S, ALLS_VARS[:i], 1) == (Combinator(ALLS_VARS[0],
1531  Combinator(ALLS_VARS[1],
1532  ALLS_VARS[2]),
1533  *ALLS_VARS[3:i]), 1)
1534  assert func_B(Atom_S, ALLS_VARS[:i], 2) == (Combinator(ALLS_VARS[0],
1535  Combinator(ALLS_VARS[1],
1536  ALLS_VARS[2]),
1537  *ALLS_VARS[3:i]), 1)
1538  assert func_B(Atom_S, ALLS_VARS[:i], None) == (Combinator(ALLS_VARS[0],
1539  Combinator(ALLS_VARS[1],
1540  ALLS_VARS[2]),
1541  *ALLS_VARS[3:i]), 1)
1542  print('ok'); sys.stdout.flush()
1543 
1544 
1545  print('func_C()...', end=''); sys.stdout.flush()
1546  assert func_C(Atom_K, (), 0) == (Combinator(Atom_K), 0)
1547  assert func_C(Atom_K, (), 1) == (Combinator(Atom_K), 0)
1548  assert func_C(Atom_K, (), 2) == (Combinator(Atom_K), 0)
1549  assert func_C(Atom_K, (), None) == (Combinator(Atom_K), 0)
1550 
1551  assert func_C(Atom_S, (), 0) == (Combinator(Atom_S), 0)
1552  assert func_C(Atom_S, (), 1) == (Combinator(Atom_S), 0)
1553  assert func_C(Atom_S, (), 2) == (Combinator(Atom_S), 0)
1554  assert func_C(Atom_S, (), None) == (Combinator(Atom_S), 0)
1555 
1556  assert func_C(Atom_K, (Vx, ), 0) == (Combinator(Atom_K, Vx), 0)
1557  assert func_C(Atom_K, (Vx, ), 1) == (Combinator(Atom_K, Vx), 0)
1558  assert func_C(Atom_K, (Vx, ), 2) == (Combinator(Atom_K, Vx), 0)
1559  assert func_C(Atom_K, (Vx, ), None) == (Combinator(Atom_K, Vx), 0)
1560 
1561  assert func_C(Atom_S, (Vx, ), 0) == (Combinator(Atom_S, Vx), 0)
1562  assert func_C(Atom_S, (Vx, ), 1) == (Combinator(Atom_S, Vx), 0)
1563  assert func_C(Atom_S, (Vx, ), 2) == (Combinator(Atom_S, Vx), 0)
1564  assert func_C(Atom_S, (Vx, ), None) == (Combinator(Atom_S, Vx), 0)
1565 
1566  assert func_C(Atom_K, (Vx, Vy), 0) == (Combinator(Atom_K, Vx, Vy), 0)
1567  assert func_C(Atom_K, (Vx, Vy), 1) == (Combinator(Atom_K, Vx, Vy), 0)
1568  assert func_C(Atom_K, (Vx, Vy), 2) == (Combinator(Atom_K, Vx, Vy), 0)
1569  assert func_C(Atom_K, (Vx, Vy), None) == (Combinator(Atom_K, Vx, Vy), 0)
1570 
1571  assert func_C(Atom_S, (Vx, Vy), 0) == (Combinator(Atom_S, Vx, Vy), 0)
1572  assert func_C(Atom_S, (Vx, Vy), 1) == (Combinator(Atom_S, Vx, Vy), 0)
1573  assert func_C(Atom_S, (Vx, Vy), 2) == (Combinator(Atom_S, Vx, Vy), 0)
1574  assert func_C(Atom_S, (Vx, Vy), None) == (Combinator(Atom_S, Vx, Vy), 0)
1575 
1576  for i in range(3, len(ALLS_VARS)):
1577  assert func_C(Atom_K, ALLS_VARS[:i], 0) == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1578  assert func_C(Atom_K, ALLS_VARS[:i], 1) == (Combinator(ALLS_VARS[0],
1579  ALLS_VARS[2],
1580  ALLS_VARS[1],
1581  *ALLS_VARS[3:i]), 1)
1582  assert func_C(Atom_K, ALLS_VARS[:i], 2) == (Combinator(ALLS_VARS[0],
1583  ALLS_VARS[2],
1584  ALLS_VARS[1],
1585  *ALLS_VARS[3:i]), 1)
1586  assert func_C(Atom_K, ALLS_VARS[:i], None) == (Combinator(ALLS_VARS[0],
1587  ALLS_VARS[2],
1588  ALLS_VARS[1],
1589  *ALLS_VARS[3:i]), 1)
1590 
1591  assert func_C(Atom_S, ALLS_VARS[:i], 0) == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1592  assert func_C(Atom_S, ALLS_VARS[:i], 1) == (Combinator(ALLS_VARS[0],
1593  ALLS_VARS[2],
1594  ALLS_VARS[1],
1595  *ALLS_VARS[3:i]), 1)
1596  assert func_C(Atom_S, ALLS_VARS[:i], 2) == (Combinator(ALLS_VARS[0],
1597  ALLS_VARS[2],
1598  ALLS_VARS[1],
1599  *ALLS_VARS[3:i]), 1)
1600  assert func_C(Atom_S, ALLS_VARS[:i], None) == (Combinator(ALLS_VARS[0],
1601  ALLS_VARS[2],
1602  ALLS_VARS[1],
1603  *ALLS_VARS[3:i]), 1)
1604  print('ok'); sys.stdout.flush()
1605 
1606 
1607  print('func_const()...', end=''); sys.stdout.flush()
1608  for i in range(len(ALLS_VARS)):
1609  assert func_const(Atom_K, ALLS_VARS[:i], 0) == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1610  assert func_const(Atom_K, ALLS_VARS[:i], 1) == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1611  assert func_const(Atom_K, ALLS_VARS[:i], 2) == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1612  assert func_const(Atom_K, ALLS_VARS[:i], None) \
1613  == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1614 
1615  assert func_const(Atom_S, ALLS_VARS[:i], 0) == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1616  assert func_const(Atom_S, ALLS_VARS[:i], 1) == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1617  assert func_const(Atom_S, ALLS_VARS[:i], 2) == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1618  assert func_const(Atom_S, ALLS_VARS[:i], None) \
1619  == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1620  print('ok'); sys.stdout.flush()
1621 
1622 
1623  print('func_I()...', end=''); sys.stdout.flush()
1624  assert func_I(Atom_K, (), 0) == (Combinator(Atom_K), 0)
1625  assert func_I(Atom_K, (), 1) == (Combinator(Atom_K), 0)
1626  assert func_I(Atom_K, (), 2) == (Combinator(Atom_K), 0)
1627  assert func_I(Atom_K, (), None) == (Combinator(Atom_K), 0)
1628 
1629  assert func_I(Atom_S, (), 0) == (Combinator(Atom_S), 0)
1630  assert func_I(Atom_S, (), 1) == (Combinator(Atom_S), 0)
1631  assert func_I(Atom_S, (), 2) == (Combinator(Atom_S), 0)
1632  assert func_I(Atom_S, (), None) == (Combinator(Atom_S), 0)
1633 
1634  assert func_I(Atom_K, (Vx, ), 0) == (Combinator(Atom_K, Vx), 0)
1635  assert func_I(Atom_K, (Vx, ), 1) == (Vx, 1)
1636  assert func_I(Atom_K, (Vx, ), 2) == (Vx, 1)
1637  assert func_I(Atom_K, (Vx, ), None) == (Vx, 1)
1638 
1639  assert func_I(Atom_S, (Vx, ), 0) == (Combinator(Atom_S, Vx), 0)
1640  assert func_I(Atom_S, (Vx, ), 1) == (Vx, 1)
1641  assert func_I(Atom_S, (Vx, ), 2) == (Vx, 1)
1642  assert func_I(Atom_S, (Vx, ), None) == (Vx, 1)
1643 
1644  for i in range(1, len(ALLS_VARS)):
1645  assert func_I(Atom_K, ALLS_VARS[:i], 0) == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1646  assert func_I(Atom_K, ALLS_VARS[:i], 1) == (Combinator(*ALLS_VARS[:i]), 1)
1647  assert func_I(Atom_K, ALLS_VARS[:i], 2) == (Combinator(*ALLS_VARS[:i]), 1)
1648  assert func_I(Atom_K, ALLS_VARS[:i], None) == (Combinator(*ALLS_VARS[:i]), 1)
1649 
1650  assert func_I(Atom_S, ALLS_VARS[:i], 0) == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1651  assert func_I(Atom_S, ALLS_VARS[:i], 1) == (Combinator(*ALLS_VARS[:i]), 1)
1652  assert func_I(Atom_S, ALLS_VARS[:i], 2) == (Combinator(*ALLS_VARS[:i]), 1)
1653  assert func_I(Atom_S, ALLS_VARS[:i], None) == (Combinator(*ALLS_VARS[:i]), 1)
1654  print('ok'); sys.stdout.flush()
1655 
1656 
1657  print('func_K()...', end=''); sys.stdout.flush()
1658  assert func_K(Atom_K, (), 0) == (Combinator(Atom_K), 0)
1659  assert func_K(Atom_K, (), 1) == (Combinator(Atom_K), 0)
1660  assert func_K(Atom_K, (), 2) == (Combinator(Atom_K), 0)
1661  assert func_K(Atom_K, (), None) == (Combinator(Atom_K), 0)
1662 
1663  assert func_K(Atom_S, (), 0) == (Combinator(Atom_S), 0)
1664  assert func_K(Atom_S, (), 1) == (Combinator(Atom_S), 0)
1665  assert func_K(Atom_S, (), 2) == (Combinator(Atom_S), 0)
1666  assert func_K(Atom_S, (), None) == (Combinator(Atom_S), 0)
1667 
1668  assert func_K(Atom_K, (Vx, ), 0) == (Combinator(Atom_K, Vx), 0)
1669  assert func_K(Atom_K, (Vx, ), 1) == (Combinator(Atom_K, Vx), 0)
1670  assert func_K(Atom_K, (Vx, ), 2) == (Combinator(Atom_K, Vx), 0)
1671  assert func_K(Atom_K, (Vx, ), None) == (Combinator(Atom_K, Vx), 0)
1672 
1673  assert func_K(Atom_S, (Vx, ), 0) == (Combinator(Atom_S, Vx), 0)
1674  assert func_K(Atom_S, (Vx, ), 1) == (Combinator(Atom_S, Vx), 0)
1675  assert func_K(Atom_S, (Vx, ), 2) == (Combinator(Atom_S, Vx), 0)
1676  assert func_K(Atom_S, (Vx, ), None) == (Combinator(Atom_S, Vx), 0)
1677 
1678  for i in range(2, len(ALLS_VARS)):
1679  assert func_K(Atom_K, ALLS_VARS[:i], 0) == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1680  assert func_K(Atom_K, ALLS_VARS[:i], 1) \
1681  == (Combinator(ALLS_VARS[0], *ALLS_VARS[2:i]), 1)
1682  assert func_K(Atom_K, ALLS_VARS[:i], 2) \
1683  == (Combinator(ALLS_VARS[0], *ALLS_VARS[2:i]), 1)
1684  assert func_K(Atom_K, ALLS_VARS[:i], None) \
1685  == (Combinator(ALLS_VARS[0], *ALLS_VARS[2:i]), 1)
1686 
1687  assert func_K(Atom_S, ALLS_VARS[:i], 0) == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1688  assert func_K(Atom_S, ALLS_VARS[:i], 1) \
1689  == (Combinator(ALLS_VARS[0], *ALLS_VARS[2:i]), 1)
1690  assert func_K(Atom_S, ALLS_VARS[:i], 2) \
1691  == (Combinator(ALLS_VARS[0], *ALLS_VARS[2:i]), 1)
1692  assert func_K(Atom_S, ALLS_VARS[:i], None) \
1693  == (Combinator(ALLS_VARS[0], *ALLS_VARS[2:i]), 1)
1694  print('ok'); sys.stdout.flush()
1695 
1696 
1697  print('func_S()...', end=''); sys.stdout.flush()
1698  assert func_S(Atom_K, (), 0) == (Combinator(Atom_K), 0)
1699  assert func_S(Atom_K, (), 1) == (Combinator(Atom_K), 0)
1700  assert func_S(Atom_K, (), 2) == (Combinator(Atom_K), 0)
1701  assert func_S(Atom_K, (), None) == (Combinator(Atom_K), 0)
1702 
1703  assert func_S(Atom_S, (), 0) == (Combinator(Atom_S), 0)
1704  assert func_S(Atom_S, (), 1) == (Combinator(Atom_S), 0)
1705  assert func_S(Atom_S, (), 2) == (Combinator(Atom_S), 0)
1706  assert func_S(Atom_S, (), None) == (Combinator(Atom_S), 0)
1707 
1708  assert func_S(Atom_K, (Vx, ), 0) == (Combinator(Atom_K, Vx), 0)
1709  assert func_S(Atom_K, (Vx, ), 1) == (Combinator(Atom_K, Vx), 0)
1710  assert func_S(Atom_K, (Vx, ), 2) == (Combinator(Atom_K, Vx), 0)
1711  assert func_S(Atom_K, (Vx, ), None) == (Combinator(Atom_K, Vx), 0)
1712 
1713  assert func_S(Atom_S, (Vx, ), 0) == (Combinator(Atom_S, Vx), 0)
1714  assert func_S(Atom_S, (Vx, ), 1) == (Combinator(Atom_S, Vx), 0)
1715  assert func_S(Atom_S, (Vx, ), 2) == (Combinator(Atom_S, Vx), 0)
1716  assert func_S(Atom_S, (Vx, ), None) == (Combinator(Atom_S, Vx), 0)
1717 
1718  assert func_S(Atom_K, (Vx, Vy), 0) == (Combinator(Atom_K, Vx, Vy), 0)
1719  assert func_S(Atom_K, (Vx, Vy), 1) == (Combinator(Atom_K, Vx, Vy), 0)
1720  assert func_S(Atom_K, (Vx, Vy), 2) == (Combinator(Atom_K, Vx, Vy), 0)
1721  assert func_S(Atom_K, (Vx, Vy), None) == (Combinator(Atom_K, Vx, Vy), 0)
1722 
1723  assert func_S(Atom_S, (Vx, Vy), 0) == (Combinator(Atom_S, Vx, Vy), 0)
1724  assert func_S(Atom_S, (Vx, Vy), 1) == (Combinator(Atom_S, Vx, Vy), 0)
1725  assert func_S(Atom_S, (Vx, Vy), 2) == (Combinator(Atom_S, Vx, Vy), 0)
1726  assert func_S(Atom_S, (Vx, Vy), None) == (Combinator(Atom_S, Vx, Vy), 0)
1727 
1728  for i in range(3, len(ALLS_VARS)):
1729  assert func_S(Atom_K, ALLS_VARS[:i], 0) == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1730  assert func_S(Atom_K, ALLS_VARS[:i], 1) == (Combinator(ALLS_VARS[0],
1731  ALLS_VARS[2],
1732  Combinator(ALLS_VARS[1],
1733  ALLS_VARS[2]),
1734  *ALLS_VARS[3:i]), 1)
1735  assert func_S(Atom_K, ALLS_VARS[:i], 2) == (Combinator(ALLS_VARS[0],
1736  ALLS_VARS[2],
1737  Combinator(ALLS_VARS[1],
1738  ALLS_VARS[2]),
1739  *ALLS_VARS[3:i]), 1)
1740  assert func_S(Atom_K, ALLS_VARS[:i], None) == (Combinator(ALLS_VARS[0],
1741  ALLS_VARS[2],
1742  Combinator(ALLS_VARS[1],
1743  ALLS_VARS[2]),
1744  *ALLS_VARS[3:i]), 1)
1745 
1746  assert func_S(Atom_S, ALLS_VARS[:i], 0) == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1747  assert func_S(Atom_S, ALLS_VARS[:i], 1) == (Combinator(ALLS_VARS[0],
1748  ALLS_VARS[2],
1749  Combinator(ALLS_VARS[1],
1750  ALLS_VARS[2]),
1751  *ALLS_VARS[3:i]), 1)
1752  assert func_S(Atom_S, ALLS_VARS[:i], 2) == (Combinator(ALLS_VARS[0],
1753  ALLS_VARS[2],
1754  Combinator(ALLS_VARS[1],
1755  ALLS_VARS[2]),
1756  *ALLS_VARS[3:i]), 1)
1757  assert func_S(Atom_S, ALLS_VARS[:i], None) == (Combinator(ALLS_VARS[0],
1758  ALLS_VARS[2],
1759  Combinator(ALLS_VARS[1],
1760  ALLS_VARS[2]),
1761  *ALLS_VARS[3:i]), 1)
1762  print('ok'); sys.stdout.flush()
1763 
1764 
1765  print('func_W()...', end=''); sys.stdout.flush()
1766  assert func_W(Atom_K, (), 0) == (Combinator(Atom_K), 0)
1767  assert func_W(Atom_K, (), 1) == (Combinator(Atom_K), 0)
1768  assert func_W(Atom_K, (), 2) == (Combinator(Atom_K), 0)
1769  assert func_W(Atom_K, (), None) == (Combinator(Atom_K), 0)
1770 
1771  assert func_W(Atom_S, (), 0) == (Combinator(Atom_S), 0)
1772  assert func_W(Atom_S, (), 1) == (Combinator(Atom_S), 0)
1773  assert func_W(Atom_S, (), 2) == (Combinator(Atom_S), 0)
1774  assert func_W(Atom_S, (), None) == (Combinator(Atom_S), 0)
1775 
1776  assert func_W(Atom_K, (Vx, ), 0) == (Combinator(Atom_K, Vx), 0)
1777  assert func_W(Atom_K, (Vx, ), 1) == (Combinator(Atom_K, Vx), 0)
1778  assert func_W(Atom_K, (Vx, ), 2) == (Combinator(Atom_K, Vx), 0)
1779  assert func_W(Atom_K, (Vx, ), None) == (Combinator(Atom_K, Vx), 0)
1780 
1781  assert func_W(Atom_S, (Vx, ), 0) == (Combinator(Atom_S, Vx), 0)
1782  assert func_W(Atom_S, (Vx, ), 1) == (Combinator(Atom_S, Vx), 0)
1783  assert func_W(Atom_S, (Vx, ), 2) == (Combinator(Atom_S, Vx), 0)
1784  assert func_W(Atom_S, (Vx, ), None) == (Combinator(Atom_S, Vx), 0)
1785 
1786  for i in range(2, len(ALLS_VARS)):
1787  assert func_W(Atom_K, ALLS_VARS[:i], 0) == (Combinator(Atom_K, *ALLS_VARS[:i]), 0)
1788  assert func_W(Atom_K, ALLS_VARS[:i], 1) \
1789  == (Combinator(ALLS_VARS[0], ALLS_VARS[1], ALLS_VARS[1], *ALLS_VARS[2:i]), 1)
1790  assert func_W(Atom_K, ALLS_VARS[:i], 2) \
1791  == (Combinator(ALLS_VARS[0], ALLS_VARS[1], ALLS_VARS[1], *ALLS_VARS[2:i]), 1)
1792  assert func_W(Atom_K, ALLS_VARS[:i], None) \
1793  == (Combinator(ALLS_VARS[0], ALLS_VARS[1], ALLS_VARS[1], *ALLS_VARS[2:i]), 1)
1794 
1795  assert func_W(Atom_S, ALLS_VARS[:i], 0) == (Combinator(Atom_S, *ALLS_VARS[:i]), 0)
1796  assert func_W(Atom_S, ALLS_VARS[:i], 1) \
1797  == (Combinator(ALLS_VARS[0], ALLS_VARS[1], ALLS_VARS[1], *ALLS_VARS[2:i]), 1)
1798  assert func_W(Atom_S, ALLS_VARS[:i], 2) \
1799  == (Combinator(ALLS_VARS[0], ALLS_VARS[1], ALLS_VARS[1], *ALLS_VARS[2:i]), 1)
1800  assert func_W(Atom_S, ALLS_VARS[:i], None) \
1801  == (Combinator(ALLS_VARS[0], ALLS_VARS[1], ALLS_VARS[1], *ALLS_VARS[2:i]), 1)
1802  print('ok'); sys.stdout.flush()
1803 
1804 
1805  print('func_x()...', end=''); sys.stdout.flush()
1806  print('???', end='')
1807  print('ok'); sys.stdout.flush()
1808 
1809 
1810  print('func_y()...', end=''); sys.stdout.flush()
1811  print('???', end='')
1812  print('ok'); sys.stdout.flush()
1813 
1814 
1815  print('func_z()...', end=''); sys.stdout.flush()
1816  print('???', end='')
1817  print('ok'); sys.stdout.flush()
1818 
1819 
1820 
1821  print()
1822  print()
1823  print("Atom_K: '{0}'".format(Atom_K)); sys.stdout.flush()
1824  print("Atom_S: '{0}'".format(Atom_S)); sys.stdout.flush()
1825  print("Atom_Vx: '{0}'".format(Atom_Vx)); sys.stdout.flush()
1826  print("Atom_Vy: '{0}'".format(Atom_Vy)); sys.stdout.flush()
1827  print("Atom_Vz: '{0}'".format(Atom_Vz)); sys.stdout.flush()
1828 
1829 
1830  print()
1831  print('Atom()...', end=''); sys.stdout.flush()
1832  assert Atom_K._f == func_K, Atom_K._f
1833  assert Atom_K._s == 'K', Atom_K._s
1834 
1835  assert Atom_S._f == func_S, Atom_S._f
1836  assert Atom_S._s == 'S', Atom_S._s
1837 
1838  assert Atom('xyz_ABC')._f == func_const, Atom('xyz_ABC')._f
1839  assert Atom('xyz_ABC')._s == 'xyz_ABC', Atom('xyz_ABC')._s
1840 
1841  assert Atom('xyz_ABC', func_K)._f == func_K, Atom('xyz_ABC', func_K)._f
1842  assert Atom('xyz_ABC', func_K)._s == 'xyz_ABC', Atom('xyz_ABC', func_K)._s
1843  print('ok'); sys.stdout.flush()
1844 
1845 
1846  print('Atom.__call__()...', end=''); sys.stdout.flush()
1847  assert Atom_K() == (K, 0), Atom_K(())
1848  assert Atom_K(Vx) == (Combinator(K, Vx), 0), Atom_K(Vx)
1849  assert Atom_K(Vx, Vy) == (Vx, 1), Atom_K(Vx, Vy)
1850  assert Atom_K(Vx, Vy, Vz) == (Combinator(Vx, Vz), 1), Atom_K(Vx, Vy, Vz)
1851  assert Atom_K(Vx, Vy, Vz, nb=0) == (Combinator(K, Vx, Vy, Vz), 0), Atom_K(Vx, Vy, Vz, nb=0)
1852 
1853  assert Atom_K(B) == (Combinator(K, B), 0), Atom_K(B)
1854  assert Atom_K(B, C) == (B, 1), Atom_K(B, C)
1855 
1856  assert Atom_S() == (S, 0), Atom_S()
1857  assert Atom_S(Vx) == (Combinator(S, Vx), 0), Atom_S(Vx)
1858  assert Atom_S(Vx, Vy) == (Combinator(S, Vx, Vy), 0), Atom_S(Vx, Vy)
1859  assert Atom_S(Vx, Vy, Vz) == (Combinator(Vx,
1860  Vz,
1861  Combinator(Vy, Vz)), 1), Atom_S(Vx, Vy, Vz)
1862  assert Atom_S(Vx, Vy, Vz, Vx) == (Combinator(Vx,
1863  Vz,
1864  Combinator(Vy, Vz),
1865  Vx), 1), Atom_S(Vx, Vy, Vz, Vx)
1866  assert Atom_S(Vx, Vy, Vz, Vx, nb=0) == (Combinator(S, Vx, Vy, Vz, Vx), 0), \
1867  Atom_S(Vx, Vy, Vz, Vx, nb=0)
1868 
1869  assert Atom_S(B) == (Combinator(S, B), 0), Atom_S(B)
1870  assert Atom_S(B, C) == (Combinator(S, B, C), 0), Atom_S(B, C)
1871  assert Atom_S(B, C, I, nb=1) == (Combinator(B,
1872  I,
1873  Combinator(C, I)), 1), \
1874  Atom_S(B, C, I, nb=1)
1875 
1876  assert Atom('_const')() == (Combinator(Atom('_const')), 0), (x, Atom('_const')())
1877 
1878  for x in STDS[:-1 if debug.assertspeed > debug.ASSERT_NORMAL else 7]:
1879  assert Atom('_const')(x) == (Combinator(Atom('_const'), x), 0), \
1880  (x, Atom('_const')(x))
1881 
1882  assert Atom_K(x) == (Combinator(K, x), 0), (x, Atom_K(x))
1883  assert Atom_K(x, nb=None) == (Combinator(K, x), 0), (x, Atom_K(x, nb=None))
1884  assert Atom_K(x, nb=0) == (Combinator(K, x), 0), (x, Atom_K(x, nb=0))
1885 
1886  assert Atom_S(x)[0] == Combinator(S, x), (x, Atom_S(x))
1887 
1888  for y in STDS[:-1 if debug.assertspeed > debug.ASSERT_NORMAL else 7]:
1889  assert Atom('_const')(x, y) == (Combinator(Atom('_const'), x, y), 0),\
1890  (x, Atom('_const')(x, y))
1891 
1892  assert Atom_K(x, y) == (x, 1), (x, y, Atom_K(x, y))
1893  assert Atom_K(x, y, nb=None) == (x, 1), (x, y, Atom_K(x, y, nb=None))
1894  assert Atom_K(x, y, nb=0) == (Combinator(K, x, y), 0), (x, Atom_K(x, y, nb=0))
1895 
1896  assert Atom_S(x, y)[0] == Combinator(S, x, y), (x, y, Atom_S(x, y))
1897 
1898  for z in STDS[:-1 if debug.assertspeed > debug.ASSERT_NORMAL else 5]:
1899  assert Atom_K(x, y, z, nb=0) == (Combinator(K, x, y, z), 0), \
1900  (x, y, z, Atom_K(x, y, z, nb=0))
1901  assert Atom_K(x, y, z, nb=1) == (Combinator(x, z), 1), \
1902  (x, y, z, Atom_K(x, y, z, nb=1))
1903  assert Atom_K(x, y, z, nb=2)[0] == Combinator(x, z)(nb=1)[0], \
1904  (x, y, z, Atom_K(x, y, z, nb=2), Combinator(x, z)(nb=1))
1905 
1906  assert Atom_S(x, y, z, nb=0) == (Combinator(S, x, y, z), 0), \
1907  (x, y, z, Atom_S(x, y, z, nb=0))
1908  assert Atom_S(x, y, z, nb=1) == (Combinator(x, z, Combinator(y, z)), 1), \
1909  (x, y, z, Atom_S(x, y, z, nb=1))
1910  assert Atom_S(x, y, z, nb=2)[0] == Combinator(x, z, Combinator(y, z))(nb=1)[0],\
1911  (x, y, z, Atom_S(x, y, z, nb=2))
1912 
1913  assert Atom_S(x, y, z, Vx, nb=1) \
1914  == (Combinator(x, z, Combinator(y, z), Vx), 1), \
1915  (x, y, z, Atom_S(x, y, z, Vx, nb=1))
1916 
1917  assert Atom_K(Vx, x, Vy, nb=3)[0] == Combinator(Vx, Vy)(nb=2)[0], \
1918  (Vx, x, Vy, Atom_K(Vx, x, Vy, nb=3), Combinator(Vx, Vy)(nb=2))
1919  assert Atom_K(Vx, x, Vy, nb=None)[0] == Combinator(Vx, Vy)(nb=None)[0], \
1920  (Vx, x, Vy, Atom_K(Vx, x, Vy, nb=None), Combinator(Vx, Vy)(nb=None))
1921  assert Atom_K(Vx, x, Vy)[0] == Combinator(Vx, Vy)()[0], \
1922  (Vx, x, Vy, Atom_K(Vx, x, Vy), Combinator(Vx, Vy)())
1923 
1924  if debug.assertspeed <= debug.ASSERT_NORMAL:
1925  print(debug.assertspeed_str(), end='')
1926  print('ok'); sys.stdout.flush()
1927 
1928 
1929  print('Atom.__cmp__()...', end=''); sys.stdout.flush()
1930  if sys.version_info[0] >= 3: # La fonction built-in cmp() n'existe plus sous Python 3
1931  def mycmp(a, b):
1932  return a.__cmp__(b)
1933  else:
1934  def mycmp(a, b):
1935  return cmp(a, b)
1936 
1937  assert mycmp(Atom_K, Atom_K) == 0, mycmp(Atom_K, Atom_K)
1938  assert mycmp(Atom_S, Atom_S) == 0, mycmp(Atom_S, Atom_S)
1939  assert mycmp(Atom_K, Atom_S) < 0, mycmp(Atom_K, Atom_S)
1940  assert mycmp(Atom_S, Atom_K) > 0, mycmp(Atom_S, Atom_K)
1941 
1942  assert mycmp(Atom_K, Atom('K')) == 0, mycmp(Atom_K, Atom('K'))
1943  assert mycmp(Atom_K, Atom('K', func_S)) == 0, mycmp(Atom_K, Atom('K', func_S))
1944 
1945  assert mycmp(Atom_S, Atom('K')) > 0, mycmp(Atom_S, Atom('K'))
1946  assert mycmp(Atom_S, Atom('K', func_S)) > 0, mycmp(Atom_S, Atom('K', func_S))
1947 
1948  assert mycmp(Atom_S, Atom('S')) == 0, mycmp(Atom_S, Atom('S'))
1949  assert mycmp(Atom_S, Atom('S', func_K)) == 0, mycmp(Atom_S, Atom('S', func_K))
1950 
1951  assert mycmp(Atom_K, Atom('S')) < 0, mycmp(Atom_K, Atom('S'))
1952  assert mycmp(Atom_K, Atom('S', func_K)) < 0, mycmp(Atom_K, Atom('S', func_K))
1953 
1954  assert mycmp(Atom_K, Atom('k')) < 0, mycmp(Atom_K, Atom('k'))
1955  assert mycmp(Atom_K, Atom('K_')) < 0, mycmp(Atom_K, Atom('K_'))
1956  print('ok'); sys.stdout.flush()
1957 
1958 
1959  print('Atom.__eq__()...', end=''); sys.stdout.flush()
1960  assert Atom_K == Atom_K, Atom_K
1961  assert Atom_S == Atom_S, Atom_S
1962  assert not(Atom_K == Atom_S), (Atom_K, Atom_S)
1963  assert not(Atom_S == Atom_K), (Atom_S, Atom_K)
1964  assert not(Atom_K == 'K')
1965  assert not(Atom_S == 'S')
1966 
1967  assert Atom_K == Atom('K'), (Atom_K, Atom('K'))
1968  assert Atom_K == Atom('K', func_S), (Atom_K, Atom('K', func_S))
1969 
1970  assert Atom_S == Atom('S'), (Atom_K, Atom('S'))
1971  assert Atom_S == Atom('S', func_K), (Atom_S, Atom('S', func_K))
1972 
1973  assert not(Atom_K == Atom('k')), (Atom_K, Atom('k'))
1974  assert not(Atom_K == Atom('K_')), (Atom_K, Atom('K_'))
1975  print('ok'); sys.stdout.flush()
1976 
1977 
1978  print('Atom.__ge__()...', end=''); sys.stdout.flush()
1979  assert Atom_K >= Atom_K, Atom_K
1980  assert Atom_S >= Atom_S, Atom_S
1981  assert not(Atom_K >= Atom_S), (Atom_K, Atom_S)
1982  assert Atom_S >= Atom_K, (Atom_S, Atom_K)
1983 
1984  assert Atom_K >= Atom('K'), (Atom_K, Atom('K'))
1985  assert Atom_K >= Atom('K', func_S), (Atom_K, Atom('K', func_S))
1986 
1987  assert Atom_S >= Atom('K'), (Atom_S, Atom('K'))
1988  assert Atom_S >= Atom('K', func_S), (Atom_S, Atom('K', func_S))
1989 
1990  assert Atom_S >= Atom('S'), (Atom_S, Atom('S'))
1991  assert Atom_S >= Atom('S', func_K), (Atom_S, Atom('S', func_K))
1992 
1993  assert not(Atom_K >= Atom('S')), (Atom_K, Atom('S'))
1994  assert not(Atom_K >= Atom('S', func_K)), (Atom_K, Atom('S', func_K))
1995 
1996  assert not(Atom_K >= Atom('k')), (Atom_K, Atom('k'))
1997  assert not(Atom_K >= Atom('K_')), (Atom_K, Atom('K_'))
1998  print('ok'); sys.stdout.flush()
1999 
2000 
2001  print('Atom.__gt__()...', end=''); sys.stdout.flush()
2002  assert not(Atom_K > Atom_K), Atom_K
2003  assert not(Atom_S > Atom_S), Atom_S
2004  assert not(Atom_K > Atom_S), (Atom_K, Atom_S)
2005  assert Atom_S > Atom_K, (Atom_S, Atom_K)
2006 
2007  assert not(Atom_K > Atom('K')), (Atom_K, Atom('K'))
2008  assert not(Atom_K > Atom('K', func_S)), (Atom_K, Atom('K', func_S))
2009 
2010  assert Atom_S > Atom('K'), (Atom_S, Atom('K'))
2011  assert Atom_S > Atom('K', func_S), (Atom_S, Atom('K', func_S))
2012 
2013  assert not(Atom_S > Atom('S')), (Atom_S, Atom('S'))
2014  assert not(Atom_S > Atom('S', func_K)), (Atom_S, Atom('S', func_K))
2015 
2016  assert not(Atom_K > Atom('S')), (Atom_K, Atom('S'))
2017  assert not(Atom_K > Atom('S', func_K)), (Atom_K, Atom('S', func_K))
2018 
2019  assert not(Atom_K > Atom('k')), (Atom_K, Atom('k'))
2020  assert not(Atom_K > Atom('K_')), (Atom_K, Atom('K_'))
2021  print('ok'); sys.stdout.flush()
2022 
2023 
2024  print('Atom.__hash__()...', end=''); sys.stdout.flush()
2025  assert hash(Atom_K) == hash(Atom_K)
2026  assert hash(Atom_S) == hash(Atom_S)
2027  assert hash(Atom_K) != hash(Atom_S)
2028  assert hash(Atom_S) != hash(Atom_K)
2029 
2030  assert hash(Atom_K) == hash(Atom('K'))
2031  assert hash(Atom_K) == hash(Atom('K', func_S))
2032 
2033  assert hash(Atom_S) == hash(Atom('S'))
2034  assert hash(Atom_S) == hash(Atom('S', func_K))
2035  assert hash(Atom_S) != hash(Atom('K'))
2036 
2037  assert hash(Atom_S) != hash(Atom('s'))
2038  assert hash(Atom_S) != hash(Atom('S_'))
2039 
2040  for x in (Atom_K, Atom_S, Atom_Vx, Atom_Vy, Atom_Vz):
2041  for y in (Atom_K, Atom_S, Atom_Vx, Atom_Vy, Atom_Vz):
2042  if x == y:
2043  assert hash(x) == hash(y), (hash(x), hash(y), x, y)
2044  else:
2045  assert hash(x) != hash(y), (hash(x), hash(y), x, y)
2046  print('ok'); sys.stdout.flush()
2047 
2048 
2049  print('Atom.__le__()...', end=''); sys.stdout.flush()
2050  assert Atom_K <= Atom_K, Atom_K
2051  assert Atom_S <= Atom_S, Atom_S
2052  assert Atom_K <= Atom_S, (Atom_K, Atom_S)
2053  assert not(Atom_S <= Atom_K), (Atom_S, Atom_K)
2054 
2055  assert Atom_K <= Atom('K'), (Atom_K, Atom('K'))
2056  assert Atom_K <= Atom('K', func_S), (Atom_K, Atom('K', func_S))
2057 
2058  assert not(Atom_S <= Atom('K')), (Atom_S, Atom('K'))
2059  assert not(Atom_S <= Atom('K', func_S)), (Atom_S, Atom('K', func_S))
2060 
2061  assert Atom_S <= Atom('S'), (Atom_S, Atom('S'))
2062  assert Atom_S <= Atom('S', func_K), (Atom_S, Atom('S', func_K))
2063 
2064  assert Atom_K <= Atom('S'), (Atom_K, Atom('S'))
2065  assert Atom_K <= Atom('S', func_K), (Atom_K, Atom('S', func_K))
2066 
2067  assert Atom_K <= Atom('k'), (Atom_K, Atom('k'))
2068  assert Atom_K <= Atom('K_'), (Atom_K, Atom('K_'))
2069  print('ok'); sys.stdout.flush()
2070 
2071 
2072  print('Atom.__lt__()...', end=''); sys.stdout.flush()
2073  assert not(Atom_K < Atom_K), Atom_K
2074  assert not(Atom_S < Atom_S), Atom_S
2075  assert Atom_K < Atom_S, (Atom_K, Atom_S)
2076  assert not(Atom_S < Atom_K), (Atom_S, Atom_K)
2077 
2078  assert not(Atom_K < Atom('K')), (Atom_K, Atom('K'))
2079  assert not(Atom_K < Atom('K', func_S)), (Atom_K, Atom('K', func_S))
2080 
2081  assert not(Atom_S < Atom('K')), (Atom_S, Atom('K'))
2082  assert not(Atom_S < Atom('K', func_S)), (Atom_S, Atom('K', func_S))
2083 
2084  assert not(Atom_S < Atom('S')), (Atom_S, Atom('S'))
2085  assert not(Atom_S < Atom('S', func_K)), (Atom_S, Atom('S', func_K))
2086 
2087  assert Atom_K < Atom('S'), (Atom_K, Atom('S'))
2088  assert Atom_K < Atom('S', func_K), (Atom_K, Atom('S', func_K))
2089 
2090  assert Atom_K < Atom('k'), (Atom_K, Atom('k'))
2091  assert Atom_K < Atom('K_'), (Atom_K, Atom('K_'))
2092  print('ok'); sys.stdout.flush()
2093 
2094 
2095  print('Atom.__ne__()...', end=''); sys.stdout.flush()
2096  assert not(Atom_K != Atom_K), Atom_K
2097  assert not(Atom_S != Atom_S), Atom_S
2098  assert Atom_K != Atom_S, (Atom_K, Atom_S)
2099  assert Atom_S != Atom_K, (Atom_S, Atom_K)
2100  assert Atom_K != 'K'
2101  assert Atom_S != 'S'
2102 
2103  assert not(Atom_K != Atom('K')), (Atom_K, Atom('K'))
2104  assert not(Atom_K != Atom('K', func_S)), (Atom_K, Atom('K', func_S))
2105 
2106  assert not(Atom_S != Atom('S')), (Atom_K, Atom('S'))
2107  assert not(Atom_S != Atom('S', func_K)), (Atom_S, Atom('S', func_K))
2108 
2109  assert Atom_K != Atom('k'), (Atom_K, Atom('k'))
2110  assert Atom_K != Atom('K_'), (Atom_K, Atom('K_'))
2111  print('ok'); sys.stdout.flush()
2112 
2113 
2114  print('Atom.__repr__()...', end=''); sys.stdout.flush()
2115  assert repr(Atom_K) == "Atom('K')", repr(Atom_K)
2116  assert repr(Atom_S) == "Atom('S')", repr(Atom_S)
2117 
2118  assert repr(Atom('K')) == "Atom('K')", repr(Atom('K'))
2119  assert repr(Atom('K', func_S)) == "Atom('K')", repr(Atom('K', func_S))
2120 
2121  assert repr(Atom('S')) == "Atom('S')", repr(Atom('S'))
2122  assert repr(Atom('S', func_K)) == "Atom('S')", repr(Atom('S', func_K))
2123 
2124  assert repr(Atom('xyz_ABC')) == "Atom('xyz_ABC')", repr(Atom('xyz_ABC'))
2125  print('ok'); sys.stdout.flush()
2126 
2127 
2128  print('Atom.__str__()...', end=''); sys.stdout.flush()
2129  assert str(Atom_K) == 'K', str(Atom_K)
2130  assert str(Atom_S) == 'S', str(Atom_S)
2131 
2132  assert str(Atom('K')) == 'K', str(Atom('K'))
2133  assert str(Atom('K', func_S)) == 'K', str(Atom('K', func_S))
2134 
2135  assert str(Atom('S')) == 'S', str(Atom('S'))
2136  assert str(Atom('S', func_K)) == 'S', str(Atom('S', func_K))
2137 
2138  assert str(Atom('xyz_ABC')) == 'xyz_ABC', str(Atom('xyz_ABC'))
2139  print('ok'); sys.stdout.flush()
2140 
2141 
2142  print('Atom.f()...', end=''); sys.stdout.flush()
2143  assert Atom_K.f() == func_K, (Atom_K.f(), func_K)
2144  assert Atom_S.f() == func_S, (Atom_S.f(), func_S)
2145 
2146  assert Atom('K').f() == func_const, (Atom('K').f(), func_const)
2147  assert Atom('xyz_ABC').f() == func_const, (Atom('xyz_ABC').f(), func_const)
2148 
2149  assert Atom('xyz_ABC', func_S).f() == func_S, (Atom('xyz_ABC', func_S).f(), func_S)
2150  print('ok'); sys.stdout.flush()
2151 
2152 
2153  print('Atom.nb_args()...', end=''); sys.stdout.flush()
2154  assert Atom_K.nb_args() == 2, Atom_K.nb_args()
2155  assert Atom_S.nb_args() == 3, Atom_S.nb_args()
2156 
2157  assert Atom('z', func_const).nb_args() == None, Atom('z', func_const).nb_args()
2158 
2159  assert Atom('z', func_B).nb_args() == 3, Atom('z', func_B).nb_args()
2160  assert Atom('z', func_B).nb_args(max=2) == None, Atom('z', func_B).nb_args(max=2)
2161 
2162  assert Atom('z', func_C).nb_args() == 3, Atom('z', func_C).nb_args()
2163  assert Atom('z', func_C).nb_args(max=2) == None, Atom('z', func_C).nb_args(max=2)
2164 
2165  assert Atom('z', func_I).nb_args() == 1, Atom('z', func_I).nb_args()
2166  assert Atom('z', func_I).nb_args(max=0) == None, Atom('z', func_I).nb_args(max=2)
2167 
2168  assert Atom('z', func_K).nb_args() == 2, Atom('z', func_K).nb_args()
2169  assert Atom('z', func_K).nb_args(max=1) == None, Atom('z', func_K).nb_args(max=2)
2170 
2171  assert Atom('z', func_S).nb_args() == 3, Atom('z', func_S).nb_args()
2172  assert Atom('z', func_S).nb_args(max=2) == None, Atom('z', func_S).nb_args(max=2)
2173 
2174  assert Atom('z', func_W).nb_args() == 2, Atom('z', func_W).nb_args()
2175  assert Atom('z', func_W).nb_args(max=1) == None, Atom('z', func_W).nb_args(max=2)
2176  print('ok'); sys.stdout.flush()
2177 
2178 
2179 
2180  print()
2181  print()
2182  print("BARENDREGT: '{0}'".format(BARENDREGT)); sys.stdout.flush()
2183  print("CHURCH: '{0}'".format(CHURCH)); sys.stdout.flush()
2184 
2185  print()
2186  print("K: '{0}'".format(K)); sys.stdout.flush()
2187  print("S: '{0}'".format(S)); sys.stdout.flush()
2188  print("KK: '{0}'".format(KK)); sys.stdout.flush()
2189  print("KS: '{0}'".format(KS)); sys.stdout.flush()
2190  print("SS: '{0}'".format(SS)); sys.stdout.flush()
2191  print("SK: '{0}'".format(SK)); sys.stdout.flush()
2192 
2193  print("B: '{0}'".format(B)); sys.stdout.flush()
2194  print("C: '{0}'".format(C)); sys.stdout.flush()
2195  print("I: '{0}'".format(I)); sys.stdout.flush()
2196  print("iota: '{0}'".format(iota)); sys.stdout.flush()
2197  print("KI: '{0}'".format(KI)); sys.stdout.flush()
2198  print("L: '{0}'".format(L)); sys.stdout.flush()
2199  print("M: '{0}'".format(M)); sys.stdout.flush()
2200  print("O: '{0}'".format(O)); sys.stdout.flush()
2201  print("Omega: '{0}'".format(Omega)); sys.stdout.flush()
2202  print("R: '{0}'".format(R)); sys.stdout.flush()
2203  print("T: '{0}'".format(T)); sys.stdout.flush()
2204  print("U: '{0}'".format(U)); sys.stdout.flush()
2205  print("V: '{0}'".format(V)); sys.stdout.flush()
2206  print("W: '{0}'".format(W)); sys.stdout.flush()
2207  print("Y: '{0}'".format(Y)); sys.stdout.flush()
2208 
2209  print("Bnot: '{0}'".format(Bnot)); sys.stdout.flush()
2210  print("Bnot_my: '{0}'".format(Bnot_my)); sys.stdout.flush()
2211  print("Band: '{0}'".format(Band)); sys.stdout.flush()
2212  print("Bor: '{0}'".format(Bor)); sys.stdout.flush()
2213  print("Bimp: '{0}'".format(Bimp)); sys.stdout.flush()
2214  print("Bnotrec: '{0}'".format(Bnotrec)); sys.stdout.flush()
2215 
2216  print("NBzero_is: '{0}'".format(NBzero_is)); sys.stdout.flush()
2217  print("NBsucc: '{0}'".format(NBsucc)); sys.stdout.flush()
2218  print("NBprev: '{0}'".format(NBprev)); sys.stdout.flush()
2219  print("NBadd: '{0}'".format(NBadd)); sys.stdout.flush()
2220 
2221  print("NCsucc: '{0}'".format(NCsucc)); sys.stdout.flush()
2222  print("NCadd: '{0}'".format(NCadd)); sys.stdout.flush()
2223 
2224  print("Vx: '{0}'".format(Vx)); sys.stdout.flush()
2225  print("Vy: '{0}'".format(Vy)); sys.stdout.flush()
2226  print("Vz: '{0}'".format(Vz)); sys.stdout.flush()
2227 
2228 
2229  assert str(K) == 'K', str(K)
2230  assert str(S) == 'S', str(S)
2231  assert str(KK) == 'K K', str(KK)
2232  assert str(KS) == 'K S', str(KS)
2233  assert str(SS) == 'S S', str(SS)
2234  assert str(SK) == 'S K', str(SK)
2235 
2236  assert str(B) == 'S (K S) K', str(B)
2237  assert str(C) == 'S (S (K (S (K S) K)) S) (K K)', str(C)
2238  assert str(I) == 'S K K', str(I)
2239  assert str(iota) == 'S (S (S K K) (K S)) (K K)', str(iota)
2240  assert str(KI) == 'K (S K K)', str(KI)
2241  assert str(L) == 'S (S (K S) K) (K (S (S K K) (S K K)))', str(L)
2242  assert str(M) == 'S (S K K) (S K K)', str(M)
2243  assert str(O) == 'S (S K K)', str(O)
2244  assert str(Omega) == 'S (S K K) (S K K) (S (S K K) (S K K))', str(Omega)
2245  assert str(R) == 'S (K (S (K S) K)) (S (K (S (S K K))) K)', str(R)
2246  assert str(T) == 'S (K (S (S K K))) K', str(T)
2247  assert str(U) == 'S (K (S (S K K))) (S (S K K) (S K K))', str(U)
2248  assert str(V) == 'S (K (S (S (K (S (K S) K)) S) (K K))) (S (K (S (S K K))) K)', str(V)
2249  assert str(W) == 'S S (K (S K K))', str(W)
2250  assert str(Y) == 'S (K (S (S K K) (S K K))) (S (S (K S) K) (K (S (S K K) (S K K))))', str(Y)
2251 
2252  assert str(Bnot) == 'S (S (S K K) (K (K (S K K)))) (K K)', str(Bnot)
2253  assert str(Bnot_my) == 'S (S (S K K) (S (S K K) (K (S K K)))) (K K)', str(Bnot_my)
2254  assert str(Band) == 'S (K (S (S K K) (K (K (S K K)))))', str(Band)
2255  assert str(Bor) == 'S (S K K) (K K)', str(Bor)
2256  assert str(Bimp) == 'S (K (S (S K K) (K K)))', str(Bimp)
2257  assert str(Bnotrec) == 'S (S K K) (K (K (S K K)))', str(Bnotrec)
2258 
2259  assert str(NBzero_is) == 'S (K (S (S K K))) K K', str(NBzero_is)
2260  assert str(NBsucc) == \
2261  'S (K (S (S (K (S (K S) K)) S) (K K))) (S (K (S (S K K))) K) (K (S K K))', \
2262  str(NBsucc)
2263  assert str(NBprev) == 'S (K (S (S K K))) K (K (S K K))', str(NBprev)
2264 ## assert str(NBadd) == '???', str(NBadd)
2265 
2266  assert str(NCsucc) == 'S (S (K S) K)', str(NCsucc)
2267  assert str(NCadd) == 'S (K S) K S (S (K S) K (S (K S) K))', str(NCadd)
2268 
2269  assert str(Vx) == 'x', str(Vx)
2270  assert str(Vy) == 'y', str(Vy)
2271  assert str(Vz) == 'z', str(Vz)
2272 
2273  print()
2274  print('natural_sys: {0}'.format(natural_sys))
2275  assert (natural_sys == BARENDREGT) or (natural_sys == CHURCH), \
2276  natural_sys
2277 
2278  x = sorted(str_combs.keys())
2279  print('str_combs.keys(): {0}'.format(x))
2280  for x in str_combs:
2281  assert x == str(str_combs[x]), (x, str(str_combs[x]))
2282 
2283 
2284  print()
2285  print('Combinator()...', end=''); sys.stdout.flush()
2286  assert Combinator(Atom_K) == K, Combinator(Atom_K)
2287  assert Combinator(Atom_S) == S, Combinator(Atom_S)
2288 
2289  assert Combinator(K) == K, Combinator(K)
2290  assert Combinator(S) == S, Combinator(S)
2291  assert Combinator(KS) == KS, Combinator(KS)
2292  for x in ALLS:
2293  assert Combinator(x) == x, (x, Combinator(x))
2294 
2295  assert Combinator(Atom_K, Atom_S) == KS, Combinator(Atom_K, Atom_S)
2296  assert Combinator(S, K) == SK, Combinator(S, K)
2297 
2298  assert Combinator(False) == KI, Combinator(False)
2299  assert Combinator(True) == K, Combinator(True)
2300 
2301  natural_sys = BARENDREGT
2302  assert Combinator(False) == KI, Combinator(False)
2303  assert Combinator(True) == K, Combinator(True)
2304 
2305  assert Combinator(0) == I, Combinator(0)
2306  assert Combinator(1) == Combinator(NBsucc, I), Combinator(1)
2307  assert Combinator(2) == Combinator(NBsucc, Combinator(NBsucc, I)), Combinator(2)
2308  assert Combinator(3) == Combinator(NBsucc, Combinator(NBsucc, Combinator(NBsucc, I))), \
2309  Combinator(3)
2310 
2311  natural_sys = CHURCH
2312  assert Combinator(0) == KI, Combinator(0)
2313  assert Combinator(1) == Combinator(NCsucc, KI), Combinator(1)
2314  assert Combinator(2) == Combinator(NCsucc, Combinator(NCsucc, KI)), Combinator(2)
2315  assert Combinator(3) == Combinator(NCsucc, Combinator(NCsucc, Combinator(NCsucc, KI))), \
2316  Combinator(3)
2317 
2318  assert Combinator('K') == K, Combinator('K')
2319  assert Combinator('S') == S, Combinator('S')
2320 
2321  assert Combinator('K K') == KK, Combinator('K K')
2322  assert Combinator('K S') == KS, Combinator('K S')
2323  assert Combinator('S K') == SK, Combinator('S K')
2324  assert Combinator('S S') == SS, Combinator('S S')
2325 
2326  assert Combinator('S K K') == I, Combinator('S K K')
2327 
2328  assert Combinator('S (S (K (S (K S) K)) S) (K K)') == C, \
2329  (Combinator('S (S (K (S (K S) K)) S) (K K)'), C)
2330 
2331  assert Combinator(' S (K (S(S K K)(S K K))) (S (S(K S) K)(K (S (S K K)(S K K)) )) ') == Y, \
2332  (Combinator(' S (K (S(S K K)(S K K))) (S (S(K S) K)(K (S (S K K)(S K K)) )) '), Y)
2333 
2334  for x in (ALLS if debug.assertspeed >= debug.ASSERT_NORMAL else BASICS):
2335  assert Combinator(str(x)) == x, (x, Combinator(str(x)))
2336  assert Combinator('({0})'.format(x)) == x, (x, '({0})'.format(x))
2337  for y in (ALLS if debug.assertspeed > debug.ASSERT_NORMAL else BASICS):
2338  assert Combinator('{0}({1})'.format(x, y)) == Combinator(str(x),
2339  Combinator(str(y))), \
2340  (x, y, Combinator('{0}({1})'.format(x, y)))
2341  assert Combinator('( (({0}) ) ({1}))'.format(x, y)) \
2342  == Combinator(str(x), Combinator(str(y))), \
2343  (x, y, Combinator('( (({0}) ) ({1}))'.format(x, y)))
2344 
2345  # La construction en une fois par une liste
2346  # doit être égale à la "construction parenthésée à gauche"
2347  for n in range(1, len(ALLS)):
2348  x = Combinator(*ALLS[:n])
2349  y = Combinator(ALLS[0])
2350  for i in range(1, n):
2351  y = Combinator(y, ALLS[i])
2352  assert x == y
2353  if debug.assertspeed <= debug.ASSERT_NORMAL:
2354  print(debug.assertspeed_str(), end='')
2355  print('ok'); sys.stdout.flush()
2356 
2357 
2358  print('Combinator.__and__()...', end=''); sys.stdout.flush()
2359  assert (K & K)()[0] == K, (K & K, (K & K)())
2360  assert (K & KI)()[0] == KI, (K & KI, (K & KI)())
2361  assert (KI & K)()[0] == KI, (KI & K, (KI & K)())
2362  assert (KI & KI)()[0] == KI, (KI & KI, (KI & KI)())
2363 
2364  assert (K & True)()[0] == K, (K & True, (K & True)())
2365  assert (K & False)()[0] == KI, (K & False, (K & False)())
2366  assert (KI & True)()[0] == KI, (KI & True, (KI & True)())
2367  assert (KI & False)()[0] == KI, (KI & False, (KI & False)())
2368 
2369  for x in ALLS_VARS:
2370  for y in ALLS_VARS + (True, False):
2371  assert x & y == Combinator(Band, x, y), (x, y, x & y, Combinator(Band, x, y))
2372  print('ok'); sys.stdout.flush()
2373 
2374 
2375  print('Combinator.__call__()...', end=''); sys.stdout.flush()
2376  assert K() == (K, 0), K()
2377  assert S() == (S, 0), S()
2378  assert KK() == (KK, 0), KK()
2379  assert KS() == (KS, 0), KS()
2380  assert SS() == (SS, 0), SS()
2381  assert SK() == (SK, 0), SK()
2382  for x in STABLES:
2383  assert x(nb=0) == (x, 0), (x, x(nb=0))
2384  assert x() == (x, 0), (x, x())
2385  for x in UNSTABLES:
2386  assert x(nb=0) == (x, 0), (x, x(nb=0))
2387  assert x(nb=1)[0] != x, (x, x(nb=1)[0])
2388  assert x(nb=1)[1] == 1, (x, x(nb=1)[1])
2389 
2390  assert Omega(nb=1) == (Combinator(I, M, Combinator(I, M)), 1), Omega(nb=1)
2391 
2392  assert Combinator(S, Combinator(B, B, S), KK)()[0] == C, \
2393  Combinator(S, Combinator(B, B, S), KK)()
2394 
2395  assert Combinator(W, S, K)()[0] == I, Combinator(W, S, K)()
2396 
2397  assert Combinator(S, I, I)()[0] == M, Combinator(S, I, I)()
2398  assert Combinator(W, I)()[0] == M, Combinator(W, I)()
2399 
2400  assert Combinator(B, Combinator(S, I), K)()[0] == T, Combinator(B, Combinator(S, I), K)()
2401  assert Combinator(B, O, K)()[0] == T, Combinator(B, O, K)()
2402 
2403  for x in STABLES:
2404  assert x() == (x, 0), (x, x())
2405 
2406  assert Combinator(KK, x)()[0] == K, (x, Combinator(KK, x)())
2407  assert Combinator(KS, x)()[0] == S, (x, Combinator(KS, x)())
2408  assert Combinator(I, x)()[0] == x, (x, Combinator(I, x)())
2409  if (x != M) and (x != U) and (x != Y):
2410  assert Combinator(M, x)()[0] == Combinator(x, x)()[0], \
2411  (x, Combinator(M, x)())
2412  assert Combinator(W, x)()[0] == Combinator(S, x, I), (x, Combinator(W, x)())
2413  if (x != U) and (x != Y):
2414  assert Combinator(Bnot_my, x)()[0] == Combinator(x, Combinator(x, I), K)()[0], \
2415  (x, Combinator(Bnot_my, x)())
2416 
2417  for x in UNSTABLES:
2418  assert x(nb=1)[0] != x, (x, x(nb=1))
2419  assert x(nb=1)[1] == 1, (x, x(nb=1))
2420 
2421  if debug.assertspeed >= debug.ASSERT_NORMAL:
2422  for x in STABLES:
2423  for y in STABLES:
2424  assert Combinator(K, x, y)()[0] == x, (x, y, Combinator(K, x, y)())
2425  assert Combinator(SK, x, y)()[0] == y, (x, y, Combinator(SK, x, y)())
2426  assert Combinator(KI, x, y)()[0] == y, (x, y, Combinator(KI, x, y)())
2427  assert Combinator(T, K, I, x, y)()[0] == x, (x, y, Combinator(T, K, I, x, y)())
2428  assert Combinator(T, K, S, x, y)()[0] == y, (x, y, Combinator(T, K, S, x, y)())
2429  if (x in (M, U, Y)) or (y in (M, U, Y)):
2430  continue
2431  assert Combinator(SS, x, y)()[0] == Combinator(S, y, Combinator(x, y))()[0], \
2432  (x, y, Combinator(SS, x, y)())
2433  assert Combinator(O, x, y)()[0] == Combinator(y, Combinator(x, y))()[0], \
2434  (x, y, Combinator(O, x, y)())
2435  assert Combinator(T, x, y)()[0] == Combinator(y, x)()[0], \
2436  (x, y, Combinator(T, x, y)())
2437  if x != W:
2438  assert Combinator(W, x, y)()[0] == Combinator(x, y, y)()[0], \
2439  (x, y, Combinator(W, x, y)())
2440  if debug.assertspeed > debug.ASSERT_NORMAL:
2441  for x in (K, S, KK, KS, SS, SK, B, C, I, KI, O, T, Bnot_my):
2442  for y in (K, S, KK, KS, SK, B, C, KI, Bnot_my):
2443  for z in STABLES:
2444  if (z == U) or (z == Y):
2445  continue
2446  assert Combinator(S, x, y, z)()[0] \
2447  == Combinator(x, z, Combinator(y, z))()[0], \
2448  (x, y, z, Combinator(S, x, y, z)())
2449  assert Combinator(B, x, y, z)()[0] == Combinator(x, Combinator(y, z))()[0],\
2450  (x, y, z, Combinator(B, x, y, z)())
2451  assert Combinator(C, x, y, z)()[0] == Combinator(x, z, y)()[0], \
2452  (x, y, z, Combinator(C, x, y, z)())
2453 
2454  assert Combinator(I, K)()[0] == K, Combinator(I, K)()
2455  assert Combinator(Bnot_my, K)()[0] == KI, Combinator(Bnot_my, K)()
2456  assert Combinator(Bnot_my, Combinator(I, K))()[0] == KI, \
2457  Combinator(Bnot_my, Combinator(I, K))()[0]
2458  assert Combinator(Bnot_my, KI)()[0] == K, Combinator(Bnot_my, K)()
2459  if debug.assertspeed <= debug.ASSERT_NORMAL:
2460  print(debug.assertspeed_str(), end='')
2461  print('???', end='')
2462  print('ok'); sys.stdout.flush()
2463 
2464 
2465  print('Combinator.__cmp__()...', end=''); sys.stdout.flush()
2466  print('???', end='')
2467  print('ok'); sys.stdout.flush()
2468 
2469 
2470  print('Combinator.__contains__()...', end=''); sys.stdout.flush()
2471  print('???', end='')
2472  print('ok'); sys.stdout.flush()
2473 
2474 
2475  print('Combinator.__eq__()...', end=''); sys.stdout.flush()
2476  for i in range(len(ALLS)):
2477  x = ALLS[i]
2478  assert x == x, (i, x)
2479  for j in range(len(ALLS)):
2480  y = ALLS[j]
2481  if i == j:
2482  assert y == x, (i, j, x, y)
2483  else:
2484  assert not(y == x), (i, j, x, y)
2485  print('???', end='')
2486  print('ok'); sys.stdout.flush()
2487 
2488 
2489  print('Combinator.__getitem__()...', end=''); sys.stdout.flush()
2490  print('???', end='')
2491  print('ok'); sys.stdout.flush()
2492 
2493 
2494  print('Combinator.__hash__()...', end=''); sys.stdout.flush()
2495  assert hash(K) == hash(K)
2496  assert hash(S) == hash(S)
2497  assert hash(K) != hash(S)
2498  assert hash(S) != hash(K)
2499 
2500  assert hash(K) == hash(Combinator('K'))
2501 
2502  assert hash(S) == hash(Combinator('S'))
2503  assert hash(S) != hash(Combinator('K'))
2504 
2505  for x in ALLS_VARS:
2506  for y in ALLS_VARS:
2507  if x == y:
2508  assert hash(x) == hash(y), (hash(x), hash(y), x, y)
2509  else:
2510  assert hash(x) != hash(y), (hash(x), hash(y), x, y)
2511  print('ok'); sys.stdout.flush()
2512 
2513 
2514  print('Combinator.__int__()...', end=''); sys.stdout.flush()
2515  natural_sys = BARENDREGT
2516  assert int(I) == 0, int(I)
2517  assert int(Combinator(V, KI, I)) == 1, int(Combinator(V, KI, I))
2518 
2519  natural_sys = CHURCH
2520  assert int(KI) == 0, int(KI)
2521  assert int(Combinator(S, B, KI)) == 1, int(Combinator(S, B, KI))
2522 
2523  for n in range(30):
2524  natural_sys = BARENDREGT
2525  x = Combinator(n)
2526  assert n == int(x), (n, int(x), x)
2527 
2528  natural_sys = CHURCH
2529  x = Combinator(n)
2530  assert n == int(x), (n, int(x), x)
2531  print('ok'); sys.stdout.flush()
2532 
2533 
2534  print('Combinator.__len__()...', end=''); sys.stdout.flush()
2535  print('???', end='')
2536  print('ok'); sys.stdout.flush()
2537 
2538 
2539  print('Combinator.__ne__()...', end=''); sys.stdout.flush()
2540  for i in range(len(ALLS)):
2541  x = ALLS[i]
2542  assert not(x != x), (i, x)
2543  for j in range(len(ALLS)):
2544  y = ALLS[j]
2545  if i != j:
2546  assert y != x, (i, j, x, y)
2547  else:
2548  assert not(y != x), (i, j, x, y)
2549  print('???', end='')
2550  print('ok'); sys.stdout.flush()
2551 
2552 
2553  print('Combinator.__nonzero__()...', end=''); sys.stdout.flush()
2554  assert K.__nonzero__()
2555  assert not KI.__nonzero__()
2556 
2557  for x in ALLS_VARS:
2558  assert isinstance(x.__nonzero__(), bool), (type(x.__nonzero__()), x.__nonzero__())
2559  if x == K:
2560  assert x.__nonzero__()
2561  else:
2562  assert not x.__nonzero__()
2563  print('ok'); sys.stdout.flush()
2564 
2565 
2566  print('Combinator.__or__()...', end=''); sys.stdout.flush()
2567  assert (K | K)()[0] == K, (K | K, (K | K)())
2568  assert (K | KI)()[0] == K, (K | KI, (K | KI)())
2569  assert (KI | K)()[0] == K, (KI | K, (KI | K)())
2570  assert (KI | KI)()[0] == KI, (KI | KI, (KI | KI)())
2571 
2572  assert (K | True)()[0] == K, (K | True, (K | True)())
2573  assert (K | False)()[0] == K, (K | False, (K | False)())
2574  assert (KI | True)()[0] == K, (KI | True, (KI | True)())
2575  assert (KI | False)()[0] == KI, (KI | False, (KI | False)())
2576 
2577  for x in ALLS_VARS:
2578  for y in ALLS_VARS + (True, False):
2579  assert x | y == Combinator(Bor, x, y), (x, y, x | y, Combinator(Bor, x, y))
2580  print('ok'); sys.stdout.flush()
2581 
2582 
2583  print('Combinator.__repr__()...', end=''); sys.stdout.flush()
2584  assert repr(K) == "Combinator('K')", repr(K)
2585  assert repr(S) == "Combinator('S')", repr(S)
2586  print('???', end='')
2587  print('ok'); sys.stdout.flush()
2588 
2589 
2590  print('Combinator.__str__()...', end=''); sys.stdout.flush()
2591  assert str(K) == 'K', str(K)
2592  assert str(S) == 'S', str(S)
2593  assert str(KK) == 'K K', str(KK)
2594  assert str(KS) == 'K S', str(KS)
2595  assert str(I) == 'S K K', str(I)
2596  assert str(B) == 'S (K S) K', str(B)
2597  assert str(M) == 'S (S K K) (S K K)', str(M)
2598  assert str(Y) == 'S (K (S (S K K) (S K K))) (S (S (K S) K) (K (S (S K K) (S K K))))', str(Y)
2599  assert K.__str__(allparent=True) == 'K', K.__str__(allparent=True)
2600  assert S.__str__(allparent=True) == 'S', S.__str__(allparent=True)
2601  assert KK.__str__(allparent=True) == '(K K)', KK.__str__(allparent=True)
2602  assert KS.__str__(allparent=True) == '(K S)', KS.__str__(allparent=True)
2603  assert I.__str__(allparent=True) == '((S K) K)', I.__str__(allparent=True)
2604  assert B.__str__(allparent=True) == '((S (K S)) K)', B.__str__(allparent=True)
2605  assert M.__str__(allparent=True) == '((S ((S K) K)) ((S K) K))', M.__str__(allparent=True)
2606  assert Y.__str__(allparent=True) == '((S (K ((S ((S K) K)) ((S K) K))))' \
2607  + ' ((S ((S (K S)) K)) (K ((S ((S K) K)) ((S K) K)))))', \
2608  Y.__str__(allparent=True)
2609  print('???', end='')
2610  print('ok'); sys.stdout.flush()
2611 
2612 
2613  print('Combinator.__xor__()...', end=''); sys.stdout.flush()
2614  print('???', end='')
2615  print('ok'); sys.stdout.flush()
2616 
2617 
2618  print('Combinator.atomic_is()...', end=''); sys.stdout.flush()
2619  print('???', end='')
2620  print('ok'); sys.stdout.flush()
2621 
2622 
2623  print('Combinator.bnot()...', end=''); sys.stdout.flush()
2624  assert K.bnot()()[0] == KI, (K.bnot(), KI.bnot()())
2625  assert KI.bnot()()[0] == K, (KI.bnot(), K.bnot()())
2626 
2627  for x in ALLS_VARS:
2628  assert x.bnot() == Combinator(Bnot, x), (x, x.bnot(), Combinator(Bnot, x))
2629  print('ok'); sys.stdout.flush()
2630 
2631 
2632  print('Combinator.change_atom()...', end=''); sys.stdout.flush()
2633  assert K.change_atom(Atom_K, Atom_S) == S, K.change_atome(Atom_K, Atom_S)
2634  assert K.change_atom(Atom_K, S) == S, K.change_atome(Atom_K, S)
2635  assert K.change_atom(Atom('K'), S) == S, K.change_atome(Atom('K'), S)
2636  assert K.change_atom(Atom_K, Atom('S')) == S, K.change_atome(Atom_K, Atom('S'))
2637  assert K.change_atom(K[0], S) == S, K.change_atome(K[0], S)
2638 
2639  assert K.change_atom(Atom_K, Atom_K) == K, K.change_atome(Atom_K, Atom_K)
2640  assert K.change_atom(Atom_K, K) == K, K.change_atome(Atom_K, K)
2641 
2642  assert S.change_atom(Atom_S, Atom_K) == K, S.change_atome(Atom_S, Atom_K)
2643  assert S.change_atom(Atom_S, K) == K, S.change_atome(Atom_S, K)
2644  assert S.change_atom(Atom('S'), K) == K, S.change_atome(Atom('S'), K)
2645  assert S.change_atom(Atom_S, Atom('K')) == K, S.change_atome(Atom_S, Atom('K'))
2646  assert S.change_atom(S[0], Atom('K')) == K, S.change_atome(S[0], Atom('K'))
2647 
2648  assert S.change_atom(Atom_S, Atom_S) == S, S.change_atome(Atom_S, Atom_S)
2649  assert S.change_atom(Atom_S, S) == S, S.change_atome(Atom_S, S)
2650 
2651  assert str(M.change_atom(Atom_K, S)) == 'S (S S S) (S S S)', str(M.change_atom(Atom_K, S))
2652  x = M.change_atom(Atom_K, Vx)
2653  assert str(x) == 'S (S x x) (S x x)', str(x)
2654  assert str(x.change_atom(Atom_Vx, K)) == 'S (S K K) (S K K)', str(x.change_atom(Atom_Vx, K))
2655  for x in ALLS:
2656  if x not in (S, SS):
2657  y = x.change_atom(Atom_K, Vx)
2658  assert x != y, (x, y)
2659  y = y.change_atom(Vx[0], Vz)
2660  assert x != y, (x, y)
2661  y = y.change_atom(Vz[0], K)
2662  assert x == y, (x, y)
2663 
2664  if x not in (K, KK):
2665  y = x.change_atom(Atom_S, Vz)
2666  assert x != y, (x, y)
2667  y = y.change_atom(Vz[0], Vy)
2668  assert x != y, (x, y)
2669  y = y.change_atom(Vy[0], S)
2670  assert x == y, (x, y)
2671  print('ok'); sys.stdout.flush()
2672 
2673 
2674  print('Combinator.depth()...', end=''); sys.stdout.flush()
2675  assert K.depth() == 0, K.depth()
2676  assert S.depth() == 0, S.depth()
2677  assert KK.depth() == 1, KK.depth()
2678  assert KS.depth() == 1, KS.depth()
2679  assert SS.depth() == 1, SS.depth()
2680  assert SK.depth() == 1, SK.depth()
2681 
2682  assert B.depth() == 3, B.depth()
2683  assert C.depth() == 8, C.depth()
2684  assert I.depth() == 2, I.depth()
2685  assert iota.depth() == 6, iota.depth()
2686  assert KI.depth() == 3, KI.depth()
2687  assert L.depth() == 6, L.depth()
2688  assert M.depth() == 4, M.depth()
2689  assert O.depth() == 3, O.depth()
2690  assert Omega.depth() == 5, Omega.depth()
2691  assert R.depth() == 7, R.depth()
2692  assert T.depth() == 6, T.depth()
2693  assert V.depth() == 11, V.depth()
2694  assert W.depth() == 4, W.depth()
2695  assert Y.depth() == 7, Y.depth()
2696 
2697  assert Bnot.depth() == 7, Bnot.depth()
2698  assert Band.depth() == 7, Band.depth()
2699  assert Bor.depth() == 4, Bor.depth()
2700  assert Bimp.depth() == 6, Bimp.depth()
2701  assert Bnotrec.depth() == 5, Bnotrec.depth()
2702  print('???', end='')
2703  print('ok'); sys.stdout.flush()
2704 
2705 
2706  print('Combinator.n_to()...', end=''); sys.stdout.flush()
2707  for n in range(30):
2708  natural_sys = BARENDREGT
2709  assert Combinator.n_to(n) == Combinator.n_to_Barendregt(n), \
2710  (Combinator.n_to(n), Combinator.n_to_Barendregt(n))
2711 
2712  x = Combinator.n_to(n)
2713  assert x == Combinator(n), (n, x, Combinator(n))
2714  assert n == int(x), (n, int(x), x)
2715 
2716  natural_sys = CHURCH
2717  assert Combinator.n_to(n) == Combinator.n_to_Church(n), \
2718  (Combinator.n_to(n), Combinator.n_to_Church(n))
2719 
2720  x = Combinator.n_to(n)
2721  assert x == Combinator(n), (n, x, Combinator(n))
2722  assert n == int(x), (n, int(x), x)
2723  print('ok'); sys.stdout.flush()
2724 
2725 
2726  print('Combinator.n_to_Barendregt()...', end=''); sys.stdout.flush()
2727  assert Combinator.n_to_Barendregt(0) == I, (Combinator.n_to_Barendregt(0), I)
2728  assert Combinator.n_to_Barendregt(1) == Combinator(V, KI, I), \
2729  (Combinator.n_to_Barendregt(1), Combinator(V, KI, I))
2730  assert Combinator.n_to_Barendregt(2) == Combinator(V, KI, Combinator(V, KI, I)), \
2731  (Combinator.n_to_Barendregt(2), Combinator(V, KI, Combinator(V, KI, I)))
2732  c = I
2733  for n in range(30):
2734  natural_sys = BARENDREGT
2735  assert Combinator.n_to_Barendregt(n) == c, (n, Combinator.n_to_Barendregt(n), c)
2736  if n == 0:
2737  assert Combinator(NBzero_is, c)()[0] == K, (n, Combinator.n_to_Barendregt(n), c)
2738  else:
2739  assert Combinator(NBzero_is, c)()[0] == KI, (n, Combinator.n_to_Barendregt(n), c)
2740 
2741  natural_sys = CHURCH
2742  assert Combinator.n_to_Barendregt(n) == c, (n, Combinator.n_to_Barendregt(n), c)
2743 
2744  c = Combinator(V, KI, c)
2745  print('ok'); sys.stdout.flush()
2746 
2747 
2748  print('Combinator.n_to_Church()...', end=''); sys.stdout.flush()
2749  assert Combinator.n_to_Church(0) == KI, (Combinator.n_to_Church(0), KI)
2750  assert Combinator.n_to_Church(1) == Combinator(S, B, KI), \
2751  (Combinator.n_to_Church(1), Combinator(S, B, KI))
2752  assert Combinator.n_to_Church(2) == Combinator(S, B, Combinator(S, B, KI)), \
2753  (Combinator.n_to_Church(2), Combinator(S, B, Combinator(S, B, KI)))
2754  c = KI
2755  for n in range(30):
2756  natural_sys = BARENDREGT
2757  assert Combinator.n_to_Church(n) == c, (n, Combinator.n_to_Church(n), c)
2758 
2759  natural_sys = CHURCH
2760  assert Combinator.n_to_Church(n) == c, (n, Combinator.n_to_Church(n), c)
2761 
2762  c = Combinator(S, B, c)
2763  print('ok'); sys.stdout.flush()
2764 
2765 
2766  print('Combinator.nb_atom()...', end=''); sys.stdout.flush()
2767  assert K.nb_atom() == 1, K.nb_atom()
2768  assert S.nb_atom() == 1, S.nb_atom()
2769  assert KK.nb_atom() == 2, KK.nb_atom()
2770  assert KS.nb_atom() == 2, KS.nb_atom()
2771  assert SS.nb_atom() == 2, SS.nb_atom()
2772  assert SK.nb_atom() == 2, SK.nb_atom()
2773 
2774  assert B.nb_atom() == 4, B.nb_atom()
2775  assert C.nb_atom() == 10, C.nb_atom()
2776  assert I.nb_atom() == 3, I.nb_atom()
2777  assert KI.nb_atom() == 4, KI.nb_atom()
2778  assert M.nb_atom() == 7, M.nb_atom()
2779  assert O.nb_atom() == 4, O.nb_atom()
2780  assert Omega.nb_atom() == 14, Omega.nb_atom()
2781  assert T.nb_atom() == 7, T.nb_atom()
2782  assert W.nb_atom() == 6, W.nb_atom()
2783 
2784  assert Bnot.nb_atom() == 12, Bnot.nb_atom()
2785  assert Band.nb_atom() == 11, Band.nb_atom()
2786  assert Bor.nb_atom() == 6, Bor.nb_atom()
2787  assert Bimp.nb_atom() == 8, Bimp.nb_atom()
2788  assert Bnotrec.nb_atom() == 9, Bnotrec.nb_atom()
2789 
2790  for x in ALLS:
2791  if x.atomic_is():
2792  assert x.nb_atom() == 1, (x.nb_atom(), x)
2793  else:
2794  assert x.nb_atom() > 1, (x.nb_atom(), x)
2795  print('???', end='')
2796  print('ok'); sys.stdout.flush()
2797 
2798 
2799  print('Combinator.stable_is()...', end=''); sys.stdout.flush()
2800  for x in STABLES + VARS:
2801  assert x.stable_is()
2802  for x in UNSTABLES:
2803  assert not x.stable_is()
2804  print('???', end='')
2805  print('ok'); sys.stdout.flush()
2806 
2807 
2808  print('Combinator.str_to()...', end=''); sys.stdout.flush()
2809  assert Combinator.str_to('K') == K, Combinator.str_to('K')
2810  assert Combinator.str_to('S') == S, Combinator.str_to('S')
2811 
2812  assert Combinator.str_to('K K') == KK, Combinator.str_to('K K')
2813  assert Combinator.str_to('K S') == KS, Combinator.str_to('K S')
2814  assert Combinator.str_to('S K') == SK, Combinator.str_to('S K')
2815  assert Combinator.str_to('S S') == SS, Combinator.str_to('S S')
2816 
2817  assert Combinator.str_to('S K K') == I, Combinator.str_to('S K K')
2818 
2819  assert Combinator.str_to('S (S (K (S (K S) K)) S) (K K)') == C, \
2820  (Combinator.str_to('S (S (K (S (K S) K)) S) (K K)'), C)
2821 
2822  assert Combinator.str_to(' S (K (S(S K K)(S K K))) '
2823  + '(S (S(K S) K)(K (S (S K K)(S K K)) )) ') == Y, \
2824  (Combinator.str_to(' S (K (S(S K K)(S K K))) '
2825  + '(S (S(K S) K)(K (S (S K K)(S K K)) )) '), Y)
2826 
2827  for x in (ALLS if debug.assertspeed >= debug.ASSERT_NORMAL else BASICS):
2828  assert Combinator.str_to(str(x)) == x, (x, Combinator.str_to(str(x)))
2829  assert Combinator.str_to('({0})'.format(x)) == x, (x, '({0})'.format(x))
2830  for y in (ALLS if debug.assertspeed > debug.ASSERT_NORMAL else BASICS):
2831  assert Combinator.str_to('{0}({1})'.format(x, y)) \
2832  == Combinator(Combinator.str_to(str(x)), Combinator.str_to(str(y))), \
2833  (x, y, Combinator.str_to('{0}({1})'.format(x, y)))
2834  assert Combinator.str_to('( (({0}) ) ({1}))'.format(x, y)) \
2835  == Combinator(Combinator.str_to(str(x)), Combinator.str_to(str(y))), \
2836  (x, y, Combinator.str_to('( (({0}) ) ({1}))'.format(x, y)))
2837  if debug.assertspeed <= debug.ASSERT_NORMAL:
2838  print(debug.assertspeed_str(), end='')
2839  print('???', end='')
2840  print('ok'); sys.stdout.flush()
2841 
2842 
2843 
2844  print()
2845  print('Kxy -> x ...', end=''); sys.stdout.flush()
2846  assert func_K(Atom('z'), (Vx, ), None) == (Combinator(Atom('z'), Vx), 0), \
2847  func_K(Atom('z'), (Vx, ), None)
2848  assert func_K(Atom('z'), (Vx, Vy), None) == (Vx, 1), \
2849  func_K(Atom('z'), (Vx, Vy), None)
2850 
2851  assert Combinator(K, Vx)() == (Combinator(K, Vx), 0), Combinator(K, Vx)()
2852  assert Combinator(K, Vx, Vy)() == (Vx, 1), Combinator(K, Vx, Vy)()
2853  print('ok'); sys.stdout.flush()
2854 
2855 
2856  print('Sxyz -> xz(yz) ...', end=''); sys.stdout.flush()
2857  assert func_S(Atom('z'), (Vx, ), None) == (Combinator(Atom('z'), Vx), 0), \
2858  func_S(Atom('z'), (Vx, ), None)
2859  assert func_S(Atom('z'), (Vx, Vy), None) == (Combinator(Atom('z'), Vx, Vy), 0), \
2860  func_S(Atom('z'), (Vx, Vy), None)
2861  assert func_S(Atom('z'), (Vx, Vy, Vz), None) \
2862  == (Combinator(Vx, Vz, Combinator(Vy, Vz)), 1), \
2863  func_S(Atom('z'), (Vx, Vy, Vz), None)
2864 
2865  assert Combinator(S, Vx)() == (Combinator(S, Vx), 0), Combinator(S, Vx)()
2866  assert Combinator(S, Vx, Vy)() == (Combinator(S, Vx, Vy), 0), Combinator(S, Vx, Vy)()
2867  assert Combinator(S, Vx, Vy, Vz)() == (Combinator(Vx, Vz, Combinator(Vy, Vz)), 1), \
2868  Combinator(S, Vx, Vy, Vz)()
2869  print('ok'); sys.stdout.flush()
2870 
2871 
2872  print('Bxyz -> x(yz) ...', end=''); sys.stdout.flush()
2873  assert func_B(Atom('z'), (Vx, ), None) == (Combinator(Atom('z'), Vx), 0), \
2874  func_B(Atom('z'), (Vx, ), None)
2875  assert func_B(Atom('z'), (Vx, Vy), None) == (Combinator(Atom('z'), Vx, Vy), 0), \
2876  func_B(Atom('z'), (Vx, Vy), None)
2877  assert func_B(Atom('z'), (Vx, Vy, Vz), None) == (Combinator(Vx, Combinator(Vy, Vz)), 1), \
2878  func_B(Atom('z'), (Vx, Vy, Vz), None)
2879 
2880  assert Combinator(B, Vx, Vy, Vz)()[0] == Combinator(Vx, Combinator(Vy, Vz)), \
2881  Combinator(B, Vx, Vy, Vz)()
2882  print('ok'); sys.stdout.flush()
2883 
2884 
2885  print('Cxyz -> xzy ...', end=''); sys.stdout.flush()
2886  assert func_C(Atom('z'), (Vx, ), None) == (Combinator(Atom('z'), Vx), 0), \
2887  func_C(Atom('z'), (Vx, ), None)
2888  assert func_C(Atom('z'), (Vx, Vy), None) == (Combinator(Atom('z'), Vx, Vy), 0), \
2889  func_C(Atom('z'), (Vx, Vy), None)
2890  assert func_C(Atom('z'), (Vx, Vy, Vz), None) == (Combinator(Vx, Vz, Vy), 1), \
2891  func_C(Atom('z'), (Vx, Vy, Vz), None)
2892 
2893  assert Combinator(C, Vx, Vy, Vz)()[0] == Combinator(Vx, Vz, Vy), Combinator(C, Vx, Vy, Vz)()
2894  print('ok'); sys.stdout.flush()
2895 
2896 
2897  print('Ix -> x ...', end=''); sys.stdout.flush()
2898  assert func_I(Atom('z'), (Vx, ), None) == (Vx, 1), \
2899  func_I(Atom('z'), (Vx, ), None)
2900 
2901  assert Combinator(I, Vx)()[0] == Vx, Combinator(I, Vx)()
2902  print('ok'); sys.stdout.flush()
2903 
2904 
2905  print('iota x -> xSK ...', end=''); sys.stdout.flush()
2906  assert Combinator(iota, Vx)()[0] == Combinator(Vx, S, K), Combinator(iota, Vx)()
2907  print('ok'); sys.stdout.flush()
2908 
2909 
2910  print('Lxy -> x(yy) ...', end=''); sys.stdout.flush()
2911  assert Combinator(L, Vx, Vy)()[0] == Combinator(Vx, Combinator(Vy, Vy)), \
2912  Combinator(L, Vx, Vy)()
2913  print('ok'); sys.stdout.flush()
2914 
2915 
2916  print('Mx -> xx ...', end=''); sys.stdout.flush()
2917  assert Combinator(M, Vx)()[0] == Combinator(Vx, Vx), \
2918  Combinator(M, Vx)()
2919  print('ok'); sys.stdout.flush()
2920 
2921 
2922  print('Oxy -> y(xy) ...', end=''); sys.stdout.flush()
2923  assert Combinator(O, Vx, Vy)()[0] == Combinator(Vy, Combinator(Vx, Vy)), \
2924  Combinator(O, Vx, Vy)()
2925  print('ok'); sys.stdout.flush()
2926 
2927 
2928  print('Omega x -> Omega x ...', end=''); sys.stdout.flush()
2929 ## assert Combinator(Omega, Vx)()[0] == Combinator(Omega, Vx), \
2930 ## Combinator(Omega, Vx)()
2931  print('???', end='')
2932  print('ok'); sys.stdout.flush()
2933 
2934 
2935  print('Rxyz -> yzx ...', end=''); sys.stdout.flush()
2936  assert Combinator(R, Vx, Vy, Vz)()[0] == Combinator(Vy, Vz, Vx), Combinator(R, Vx, Vy, Vz)()
2937  print('ok'); sys.stdout.flush()
2938 
2939 
2940  print('Txy -> yx ...', end=''); sys.stdout.flush()
2941  assert Combinator(T, Vx, Vy)()[0] == Combinator(Vy, Vx), Combinator(T, Vx, Vy)()
2942  print('ok'); sys.stdout.flush()
2943 
2944 
2945  print('Uxy -> y(xxy) ...', end=''); sys.stdout.flush()
2946  assert Combinator(U, Vx, Vy)()[0] == Combinator(Vy, Combinator(Vx, Vx, Vy)), \
2947  Combinator(U, Vx, Vy)()
2948  print('ok'); sys.stdout.flush()
2949 
2950 
2951  print('Vxyz -> zxy ...', end=''); sys.stdout.flush()
2952  assert Combinator(V, Vx, Vy, Vz)()[0] == Combinator(Vz, Vx, Vy), Combinator(V, Vx, Vy, Vz)()
2953  print('ok'); sys.stdout.flush()
2954 
2955 
2956  print('Wxy -> xyy ...', end=''); sys.stdout.flush()
2957  assert func_W(Atom('z'), (Vx, ), None) == (Combinator(Atom('z'), Vx), 0), \
2958  func_W(Atom('z'), (Vx, ), None)
2959  assert func_W(Atom('z'), (Vx, Vy), None) == (Combinator(Vx, Vy, Vy), 1), \
2960  func_W(Atom('z'), (Vx, Vy), None)
2961 
2962  assert Combinator(W, Vx, Vy)()[0] == Combinator(Vx, Vy, Vy), Combinator(W, Vx, Vy)()
2963  print('ok'); sys.stdout.flush()
2964 
2965 
2966  print('Yx -> x(Yx) ...', end=''); sys.stdout.flush()
2967 ## assert Combinator(Y, Vx)()[0] == Combinator(Vx, Combinator(Y, Vx)), \
2968 ## Combinator(Y, Vx)()
2969  print('???', end='')
2970  print('ok'); sys.stdout.flush()
2971 
2972 
2973 
2974  # Teste l'évaluation de divers combinateur
2975  print()
2976  print('Evaluation of some combinators...', end='')
2977  assert Combinator(C, I, Vx, Vy)()[0] == Combinator(T, Vx, Vy)()[0]
2978 
2979  assert Combinator(B,
2980  Combinator(B, W),
2981  Combinator(B, B, C),
2982  Vx,
2983  Vy,
2984  Vz)()[0] \
2985  == Combinator(S, Vx, Vy, Vz)()[0]
2986 
2987  assert Combinator(iota, SK)()[0] == K
2988 
2989  assert Combinator(iota,
2990  Combinator(iota,
2991  Combinator(iota, iota)))()[0] == K
2992 
2993  assert Combinator(iota, K)()[0] == S
2994 
2995  assert Combinator(iota,
2996  Combinator(iota,
2997  Combinator(iota,
2998  Combinator(iota, iota))))()[0] == S
2999  print('ok'); sys.stdout.flush()
3000 
3001 
3002  # Teste l'évaluation par étapes
3003  print('Evaluation by step...', end='')
3004  for x in STABLES:
3005  if x in (Y, ) + VARS:
3006  continue
3007  x = Combinator(x, Vx, Vy, Vz)
3008  x_finish, nb = x()
3009  assert n > 0, (nb, x, x_finish)
3010  assert x != x_finish, (nb, x, x_finish)
3011 
3012  x_step = Combinator(x)
3013  for i in range(nb):
3014  x_step, nb_step = x_step(nb=1)
3015  assert nb_step == 1, (x, i, x_step, nb_step, nb, x_finish)
3016 
3017  assert x_step == x_finish, (x, x_step, nb, x_finish)
3018  assert x_step(nb=1) == (x_finish, 0), (x, x_step(nb=1), nb, x_finish)
3019  assert x_step() == (x_finish, 0), (x, x_step(), nb, x_finish)
3020 
3021  for k in range(1, nb * 2):
3022  x_step = Combinator(x)
3023  nb_total = 0
3024  for i in range((nb + k - 1)//k):
3025  x_step, nb_step = x_step(nb=k)
3026  assert 0 < nb_step <= k, (x, i, x_step, nb_step, nb, x_finish)
3027  nb_total += nb_step
3028 
3029  assert nb_total == nb, (x, x_step, nb_total, nb, x_finish)
3030  assert x_step == x_finish, (x, x_step, nb, x_finish)
3031  assert x_step(nb=1) == (x_finish, 0), (x, x_step(nb=1), nb, x_finish)
3032  assert x_step() == (x_finish, 0), (x, x_step(), nb, x_finish)
3033  print('ok'); sys.stdout.flush()
3034 
3035 
3036  # Vérifie que les "constantes" n'ont pas été modifiées
3037  assert str(K) == 'K', str(K)
3038  assert str(S) == 'S', str(S)
3039  assert str(KK) == 'K K', str(KK)
3040  assert str(KS) == 'K S', str(KS)
3041  assert str(SS) == 'S S', str(SS)
3042  assert str(SK) == 'S K', str(SK)
3043 
3044  assert str(B) == 'S (K S) K', str(B)
3045  assert str(C) == 'S (S (K (S (K S) K)) S) (K K)', str(C)
3046  assert str(I) == 'S K K', str(I)
3047  assert str(iota) == 'S (S (S K K) (K S)) (K K)', str(iota)
3048  assert str(KI) == 'K (S K K)', str(KI)
3049  assert str(L) == 'S (S (K S) K) (K (S (S K K) (S K K)))', str(L)
3050  assert str(M) == 'S (S K K) (S K K)', str(M)
3051  assert str(O) == 'S (S K K)', str(O)
3052  assert str(Omega) == 'S (S K K) (S K K) (S (S K K) (S K K))', str(Omega)
3053  assert str(R) == 'S (K (S (K S) K)) (S (K (S (S K K))) K)', str(R)
3054  assert str(T) == 'S (K (S (S K K))) K', str(T)
3055  assert str(U) == 'S (K (S (S K K))) (S (S K K) (S K K))', str(U)
3056  assert str(V) == 'S (K (S (S (K (S (K S) K)) S) (K K))) (S (K (S (S K K))) K)', str(V)
3057  assert str(W) == 'S S (K (S K K))', str(W)
3058  assert str(Y) == 'S (K (S (S K K) (S K K))) (S (S (K S) K) (K (S (S K K) (S K K))))', str(Y)
3059 
3060  assert str(Bnot) == 'S (S (S K K) (K (K (S K K)))) (K K)', str(Bnot)
3061  assert str(Bnot_my) == 'S (S (S K K) (S (S K K) (K (S K K)))) (K K)', str(Bnot_my)
3062  assert str(Band) == 'S (K (S (S K K) (K (K (S K K)))))', str(Band)
3063  assert str(Bor) == 'S (S K K) (K K)', str(Bor)
3064  assert str(Bimp) == 'S (K (S (S K K) (K K)))', str(Bimp)
3065  assert str(Bnotrec) == 'S (S K K) (K (K (S K K)))', str(Bnotrec)
3066 
3067  assert str(NBzero_is) == 'S (K (S (S K K))) K K', str(NBzero_is)
3068  assert str(NBsucc) == 'S (K (S (S (K (S (K S) K)) S) (K K))) (S (K (S (S K K))) K) ' \
3069  + '(K (S K K))', str(NBsucc)
3070  assert str(NBprev) == 'S (K (S (S K K))) K (K (S K K))', str(NBprev)
3071 
3072  assert str(NCsucc) == 'S (S (K S) K)', str(NCsucc)
3073  assert str(NCadd) == 'S (K S) K S (S (K S) K (S (K S) K))', str(NCadd)
3074 ## assert str(NBadd) == '???', str(NBadd)
3075 
3076  assert str(Vx) == 'x', str(Vx)
3077  assert str(Vy) == 'y', str(Vy)
3078  assert str(Vz) == 'z', str(Vz)
3079  debug.test_end()
3080 
3081  main_test()
3082 ##\endcond MAINTEST