refonte de la construction des lambda-termes
This commit is contained in:
parent
b4b9bb8b22
commit
7c957049db
1581
lambda_calcul.ipynb
1581
lambda_calcul.ipynb
File diff suppressed because it is too large
Load Diff
241
lambda_calcul.md
241
lambda_calcul.md
@ -28,10 +28,11 @@ Voici la grammaire du langage décrivant les $\lambda$-termes
|
|||||||
## La classe `Lambda_terme`
|
## La classe `Lambda_terme`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
T1 = Lambda_terme(0, "x")
|
T1 = Lambda_terme("x")
|
||||||
T2 = Lambda_terme(1, "x", T1)
|
T2 = Lambda_terme("(x x)")
|
||||||
T3 = Lambda_terme(2, T2, T1)
|
T3 = Lambda_terme("!x.x")
|
||||||
T4 = Lambda_terme.cree('!x.(x x)')
|
T4 = Lambda_terme('!x.(x x)')
|
||||||
|
T5 = Lambda_terme('(!x.(x y) z)')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -39,55 +40,68 @@ print(T1)
|
|||||||
print(T2)
|
print(T2)
|
||||||
print(T3)
|
print(T3)
|
||||||
print(T4)
|
print(T4)
|
||||||
|
print(T5)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
tuple(t.est_variable() for t in (T1, T2, T3, T4))
|
termes = (T1, T2, T3, T4, T5)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
tuple(t.est_abstraction() for t in (T1, T2, T3, T4))
|
tuple(t.est_variable() for t in termes)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
tuple(t.est_application() for t in (T1, T2, T3, T4))
|
tuple(t.est_abstraction() for t in termes)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
tuple(t.est_redex() for t in (T1, T2, T3, T4))
|
tuple(t.est_application() for t in termes)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
tuple(t.est_forme_normale() for t in (T1, T2, T3, T4))
|
tuple(t.est_redex() for t in termes)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
tuple(t.variables_libres() for t in (T1, T2, T3, T4))
|
tuple(t.est_forme_normale() for t in termes)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(T1, '-->', T1.subs('y', Lambda_terme.cree('(y x)')))
|
tuple(t.variables_libres() for t in termes)
|
||||||
print(T1, '-->', T1.subs('x', Lambda_terme.cree('(y x)')))
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
T5 = Lambda_terme.cree('!x.y')
|
print(T1, '-->', T1.subs('y', Lambda_terme('(y x)')))
|
||||||
print(T5, '-->', T5.subs('x', Lambda_terme.cree('(y z)')))
|
print(T1, '-->', T1.subs('x', Lambda_terme('(y x)')))
|
||||||
print(T5, '-->', T5.subs('y', Lambda_terme.cree('(t z)')))
|
|
||||||
print(T5, '-->', T5.subs('y', Lambda_terme.cree('(x z)')))
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(T3, '-->', T3.subs('y', Lambda_terme.cree('(y x)')))
|
T5 = Lambda_terme('!x.y')
|
||||||
print(T3, '-->', T3.subs('x', Lambda_terme.cree('(y x)')))
|
print(T5, '-->', T5.subs('x', Lambda_terme('(y z)')))
|
||||||
|
print(T5, '-->', T5.subs('y', Lambda_terme('(t z)')))
|
||||||
|
print(T5, '-->', T5.subs('y', Lambda_terme('(x z)')))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
print(T3, '-->', T3.subs('y', Lambda_terme('(y x)')))
|
||||||
|
print(T3, '-->', T3.subs('x', Lambda_terme('(y x)')))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
OMEGA = Lambda_terme.cree('(!x.(x x) !x.(x x))')
|
for t in termes:
|
||||||
|
for v in ('x', 'y'):
|
||||||
|
print(t.abstrait(v))
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
for t1 in termes:
|
||||||
|
for t2 in termes:
|
||||||
|
print(t1.applique(t2))
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
OMEGA = Lambda_terme('(!x.(x x) !x.(x x))')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -117,119 +131,100 @@ print(est_red)
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
res, est_red = Lambda_terme.cree('(!x.(eric x) vero)').reduit()
|
res, est_red = Lambda_terme('(!x.(eric x) vero)').reduit()
|
||||||
print(res, est_red)
|
print(res, est_red)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def calcul(lambda_terme, nb_etapes_max=100, verbose=False):
|
OMEGA.forme_normale(nb_etapes_max=10, verbose=True)
|
||||||
etape = 0
|
|
||||||
forme_normale_atteinte = False
|
|
||||||
if verbose: print(lambda_terme)
|
|
||||||
while not forme_normale_atteinte and etape < nb_etapes_max:
|
|
||||||
etape += 1
|
|
||||||
terme_reduit, est_reduit = lambda_terme.reduit()
|
|
||||||
if verbose: print('{:3d}: ---> {:s}'.format(etape, str(lambda_terme), str(terme_reduit)))
|
|
||||||
forme_normale_atteinte = not est_reduit
|
|
||||||
lambda_terme = terme_reduit
|
|
||||||
if forme_normale_atteinte:
|
|
||||||
if verbose: print('Forme normale calculée : {:s}'.format(str(terme_reduit)))
|
|
||||||
return terme_reduit
|
|
||||||
else:
|
|
||||||
if verbose: print('Pas de forme normale atteinte après {:d} étapes de réduction'.format(etape))
|
|
||||||
return None
|
|
||||||
```
|
|
||||||
|
|
||||||
```python
|
|
||||||
calcul(OMEGA, nb_etapes_max=10, verbose=True)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Entiers, successeurs, addition, multiplication et exponentiation
|
## Entiers, successeurs, addition, multiplication et exponentiation
|
||||||
|
|
||||||
```python
|
```python
|
||||||
ZERO = Lambda_terme.cree('!f.!x.x')
|
ZERO = Lambda_terme('!f.!x.x')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
UN = Lambda_terme.cree('!f.!x.(f x)')
|
UN = Lambda_terme('!f.!x.(f x)')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
DEUX = Lambda_terme.cree('!f.!x.(f (f x))')
|
DEUX = Lambda_terme('!f.!x.(f (f x))')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
SUC = Lambda_terme.cree('!n.!f.!x.(f ((n f) x))')
|
SUC = Lambda_terme('!n.!f.!x.(f ((n f) x))')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
TROIS = calcul(SUC.applique(DEUX), verbose=True)
|
TROIS = SUC.applique(DEUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(TROIS.applique(SUC).applique(ZERO), verbose=True)
|
TROIS.applique(SUC).applique(ZERO).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
ADD = Lambda_terme.cree('!n.!m.!f.!x.((n f) ((m f) x))')
|
ADD = Lambda_terme('!n.!m.!f.!x.((n f) ((m f) x))')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
QUATRE = calcul(ADD.applique(UN).applique(TROIS), verbose=True)
|
QUATRE = ADD.applique(UN).applique(TROIS).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
CINQ = calcul(ADD.applique(TROIS).applique(DEUX), verbose=True)
|
CINQ = ADD.applique(TROIS).applique(DEUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
SEPT = calcul(ADD.applique(QUATRE).applique(TROIS), verbose=True)
|
SEPT = ADD.applique(QUATRE).applique(TROIS).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
MUL = Lambda_terme.cree('!n.!m.!f.(n (m f))')
|
MUL = Lambda_terme('!n.!m.!f.(n (m f))')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
SIX = calcul(MUL.applique(DEUX).applique(TROIS), verbose=True)
|
SIX = MUL.applique(DEUX).applique(TROIS).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
EXP = Lambda_terme.cree('!n.!m.(m n)')
|
EXP = Lambda_terme('!n.!m.(m n)')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
HUIT = calcul(EXP.applique(DEUX).applique(TROIS), verbose=True)
|
HUIT = EXP.applique(DEUX).applique(TROIS).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
NEUF = calcul(EXP.applique(TROIS).applique(DEUX), verbose=True)
|
NEUF = EXP.applique(TROIS).applique(DEUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Booléens, opérateurs logiques et conditionnelles
|
## Booléens, opérateurs logiques et conditionnelles
|
||||||
|
|
||||||
```python
|
```python
|
||||||
VRAI = Lambda_terme.cree('!x.!y.x')
|
VRAI = Lambda_terme('!x.!y.x')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
FAUX = Lambda_terme.cree('!x.!y.y')
|
FAUX = Lambda_terme('!x.!y.y')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
COND = Lambda_terme.cree('!c.!a.!s.((c a) s)')
|
COND = Lambda_terme('!c.!a.!s.((c a) s)')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(COND.applique(VRAI).applique(UN).applique(DEUX), verbose=True)
|
COND.applique(VRAI).applique(UN).applique(DEUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(COND.applique(FAUX).applique(UN).applique(DEUX), verbose=True)
|
COND.applique(FAUX).applique(UN).applique(DEUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
ET = COND.applique(Lambda_terme.cree('a')).applique(Lambda_terme.cree('b')).applique(FAUX).abstrait('b').abstrait('a')
|
ET = COND.applique(Lambda_terme('a')).applique(Lambda_terme('b')).applique(FAUX).abstrait('b').abstrait('a')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -237,55 +232,63 @@ print(ET)
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(ET.applique(VRAI).applique(VRAI), verbose=True)
|
ET.applique(VRAI).applique(VRAI).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(ET.applique(VRAI).applique(FAUX), verbose=True)
|
ET.applique(VRAI).applique(FAUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(ET.applique(FAUX).applique(VRAI), verbose=True)
|
ET.applique(FAUX).applique(VRAI).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(ET.applique(FAUX).applique(FAUX), verbose=True)
|
ET.applique(FAUX).applique(FAUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
OU = COND.applique(Lambda_terme.cree('a')).applique(VRAI).applique(Lambda_terme.cree('b')).abstrait('b').abstrait('a')
|
OU = COND.applique(Lambda_terme('a')).applique(VRAI).applique(Lambda_terme('b')).abstrait('b').abstrait('a')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(OU.applique(VRAI).applique(VRAI), verbose=True)
|
print(OU)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(OU.applique(VRAI).applique(FAUX), verbose=True)
|
OU.applique(VRAI).applique(VRAI).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(OU.applique(FAUX).applique(VRAI), verbose=True)
|
OU.applique(VRAI).applique(FAUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(OU.applique(FAUX).applique(FAUX), verbose=True)
|
OU.applique(FAUX).applique(VRAI).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
NON = COND.applique(Lambda_terme.cree('a')).applique(FAUX).applique(VRAI).abstrait('a')
|
OU.applique(FAUX).applique(FAUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(NON.applique(VRAI), verbose=True)
|
NON = COND.applique(Lambda_terme('a')).applique(FAUX).applique(VRAI).abstrait('a')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(NON.applique(FAUX), verbose=True)
|
print(NON)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
NUL = Lambda_terme.cree('!n.((n !x.{:s}) {:s})'.format(str(FAUX), str(VRAI)))
|
NON.applique(VRAI).forme_normale(verbose=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
NON.applique(FAUX).forme_normale(verbose=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
NUL = Lambda_terme('!n.((n !x.{:s}) {:s})'.format(str(FAUX), str(VRAI)))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -293,17 +296,17 @@ print(NUL)
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(NUL.applique(ZERO), verbose=True)
|
NUL.applique(ZERO).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(NUL.applique(TROIS), verbose=True)
|
NUL.applique(TROIS).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Couples
|
## Couples
|
||||||
|
|
||||||
```python
|
```python
|
||||||
CONS = COND.applique(Lambda_terme.cree('s')).applique(Lambda_terme.cree('x')).applique(Lambda_terme.cree('y')).abstrait('s').abstrait('y').abstrait('x')
|
CONS = Lambda_terme('!x.!y.!s.((({:s} s) x) y)'.format(str(COND)))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -311,11 +314,11 @@ print(CONS)
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
UN_DEUX = calcul(CONS.applique(UN).applique(DEUX), verbose=True)
|
UN_DEUX = CONS.applique(UN).applique(DEUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
CAR = Lambda_terme.cree('c').applique(VRAI).abstrait('c')
|
CAR = Lambda_terme('!c.(c {:s})'.format(str(VRAI)))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -323,120 +326,124 @@ print(CAR)
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(CAR.applique(UN_DEUX), verbose=True)
|
CAR.applique(UN_DEUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
CDR = Lambda_terme.cree('c').applique(FAUX).abstrait('c')
|
CDR = Lambda_terme('!c.(c {:s})'.format(str(FAUX)))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(CDR.applique(UN_DEUX), verbose=True)
|
print(CDR)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
M_PRED = Lambda_terme.cree('!n.(CAR ((n !c.((CONS (CDR c)) (SUC (CDR c)))) ((CONS ZERO) ZERO)))')
|
CDR.applique(UN_DEUX).forme_normale(verbose=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
M_PRED = Lambda_terme('!n.(CAR ((n !c.((CONS (CDR c)) (SUC (CDR c)))) ((CONS ZERO) ZERO)))')
|
||||||
print(M_PRED)
|
print(M_PRED)
|
||||||
PRED = M_PRED.subs('CAR', CAR).subs('CONS', CONS).subs('CDR', CDR).subs('SUC', SUC).subs('ZERO', ZERO)
|
PRED = M_PRED.subs('CAR', CAR).subs('CONS', CONS).subs('CDR', CDR).subs('SUC', SUC).subs('ZERO', ZERO)
|
||||||
print(PRED)
|
print(PRED)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(PRED.applique(DEUX), verbose=True)
|
PRED.applique(DEUX).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(PRED.applique(ZERO), verbose=True)
|
PRED.applique(ZERO).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
M_SUB = Lambda_terme.cree('!n.!m.((m PRED) n)')
|
M_SUB = Lambda_terme('!n.!m.((m PRED) n)')
|
||||||
print(M_SUB)
|
print(M_SUB)
|
||||||
SUB = M_SUB.subs('PRED', PRED)
|
SUB = M_SUB.subs('PRED', PRED)
|
||||||
print(SUB)
|
print(SUB)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(SUB.applique(TROIS).applique(UN), verbose=True)
|
SUB.applique(TROIS).applique(UN).forme_normale(verbose=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
M_INF = Lambda_terme.cree('!n.!m.(NUL ((SUB m) n))')
|
M_INF = Lambda_terme('!n.!m.(NUL ((SUB n) m))')
|
||||||
print(M_INF)
|
print(M_INF)
|
||||||
INF = M_INF.subs('NUL', NUL).subs('SUB', SUB)
|
INF = M_INF.subs('NUL', NUL).subs('SUB', SUB)
|
||||||
#lambda n: lambda m: est_nul(sub(m)(n))
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(INF.applique(TROIS).applique(UN), verbose=True)
|
print(INF.applique(TROIS).applique(UN).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(INF.applique(UN).applique(TROIS), verbose=True)
|
print(INF.applique(UN).applique(TROIS).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(INF.applique(UN).applique(UN), verbose=True)
|
print(INF.applique(UN).applique(UN).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
M_EGAL = Lambda_terme.cree('!n.!m.((ET ((INF n) m)) ((INF m) n))')
|
M_EGAL = Lambda_terme('!n.!m.((ET ((INF n) m)) ((INF m) n))')
|
||||||
print(M_EGAL)
|
print(M_EGAL)
|
||||||
EGAL = M_EGAL.subs('ET', ET).subs('INF', INF)
|
EGAL = M_EGAL.subs('ET', ET).subs('INF', INF)
|
||||||
print(EGAL)
|
print(EGAL)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(EGAL.applique(UN).applique(UN)))
|
print(EGAL.applique(UN).applique(UN).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(EGAL.applique(UN).applique(DEUX)))
|
print(EGAL.applique(UN).applique(DEUX).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
## Itération
|
## Itération
|
||||||
|
|
||||||
```python
|
```python
|
||||||
M_FACTv1 = Lambda_terme.cree('!n.(CDR ((n !c.((CONS (SUC (CAR c))) ((MUL (SUC (CAR c))) (CDR c)))) ((CONS ZERO) UN)))')
|
M_FACTv1 = Lambda_terme('!n.(CDR ((n !c.((CONS (SUC (CAR c))) ((MUL (SUC (CAR c))) (CDR c)))) ((CONS ZERO) UN)))')
|
||||||
print(M_FACTv1)
|
print(M_FACTv1)
|
||||||
FACTv1 = M_FACTv1.subs('CONS', CONS).subs('CAR', CAR).subs('CDR', CDR).subs('SUC', SUC).subs('MUL', MUL).subs('UN', UN).subs('ZERO', ZERO)
|
FACTv1 = M_FACTv1.subs('CONS', CONS).subs('CAR', CAR).subs('CDR', CDR).subs('SUC', SUC).subs('MUL', MUL).subs('UN', UN).subs('ZERO', ZERO)
|
||||||
print(FACTv1)
|
print(FACTv1)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv1.applique(ZERO)))
|
print(FACTv1.applique(ZERO).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv1.applique(UN)))
|
print(FACTv1.applique(UN).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv1.applique(DEUX)))
|
print(FACTv1.applique(DEUX).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv1.applique(DEUX), nb_etapes_max=200))
|
print(FACTv1.applique(DEUX).forme_normale(nb_etapes_max=200))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv1.applique(TROIS), nb_etapes_max=500))
|
print(FACTv1.applique(TROIS).forme_normale(nb_etapes_max=500))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv1.applique(QUATRE), nb_etapes_max=1700))
|
print(FACTv1.applique(QUATRE).forme_normale(nb_etapes_max=1700))
|
||||||
```
|
```
|
||||||
|
|
||||||
## Et la récursivité ?
|
## Et la récursivité ?
|
||||||
|
|
||||||
```python
|
```python
|
||||||
M_PHI_FACT = Lambda_terme.cree('!f.!n.(((COND ((EGAL n) ZERO)) UN) ((MUL n) (f (PRED n))))')
|
M_PHI_FACT = Lambda_terme('!f.!n.(((COND ((EGAL n) ZERO)) UN) ((MUL n) (f (PRED n))))')
|
||||||
print(M_PHI_FACT)
|
print(M_PHI_FACT)
|
||||||
PHI_FACT = M_PHI_FACT.subs('COND', COND).subs('EGAL', EGAL).subs('ZERO', ZERO).subs('UN', UN).subs('MUL', MUL).subs('PRED', PRED)
|
PHI_FACT = M_PHI_FACT.subs('COND', COND).subs('EGAL', EGAL).subs('ZERO', ZERO).subs('UN', UN).subs('MUL', MUL).subs('PRED', PRED)
|
||||||
|
print(PHI_FACT)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
BOTTOM = Lambda_terme.cree('!y.OMEGA').subs('OMEGA', OMEGA)
|
BOTTOM = Lambda_terme('!y.OMEGA').subs('OMEGA', OMEGA)
|
||||||
print(BOTTOM)
|
print(BOTTOM)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -445,11 +452,11 @@ FACT0 = PHI_FACT.applique(BOTTOM)
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACT0.applique(ZERO)))
|
print(FACT0.applique(ZERO).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(FACT0.applique(UN), verbose=True)
|
FACT0.applique(UN).forme_normale(verbose=True, nb_etapes_max=40)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -457,15 +464,15 @@ FACT1 = PHI_FACT.applique(FACT0)
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACT1.applique(ZERO)))
|
print(FACT1.applique(ZERO).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACT1.applique(UN), nb_etapes_max=200))
|
print(FACT1.applique(UN).forme_normale(nb_etapes_max=200))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
FIX_CURRY = Lambda_terme.cree('!f.(!x.(f (x x)) !x.(f (x x)))')
|
FIX_CURRY = Lambda_terme('!f.(!x.(f (x x)) !x.(f (x x)))')
|
||||||
print(FIX_CURRY)
|
print(FIX_CURRY)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -474,31 +481,31 @@ FACTv2 = FIX_CURRY.applique(PHI_FACT)
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv2.applique(ZERO)))
|
print(FACTv2.applique(ZERO).forme_normale())
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv2.applique(UN), nb_etapes_max=200))
|
print(FACTv2.applique(UN).forme_normale(nb_etapes_max=200))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv2.applique(DEUX), nb_etapes_max=700))
|
print(FACTv2.applique(DEUX).forme_normale(nb_etapes_max=700))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv2.applique(TROIS), nb_etapes_max=4000))
|
print(FACTv2.applique(TROIS).forme_normale(nb_etapes_max=4000))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
print(calcul(FACTv2.applique(QUATRE), nb_etapes_max=25000))
|
print(FACTv2.applique(QUATRE).forme_normale(nb_etapes_max=25000))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
PF = FIX_CURRY.applique(Lambda_terme.cree('M'))
|
PF = FIX_CURRY.applique(Lambda_terme('M'))
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
calcul(PF, verbose=True, nb_etapes_max=10)
|
PF.forme_normale(verbose=True, nb_etapes_max=10)
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
157
lambda_calcul.py
157
lambda_calcul.py
@ -11,6 +11,7 @@ __doc__ = """
|
|||||||
|
|
||||||
Module pour travailler avec le λ-calcul
|
Module pour travailler avec le λ-calcul
|
||||||
|
|
||||||
|
|
||||||
""".format(__author__, __date_creation__)
|
""".format(__author__, __date_creation__)
|
||||||
|
|
||||||
from sly import Lexer, Parser
|
from sly import Lexer, Parser
|
||||||
@ -45,19 +46,37 @@ class Lambda_lexer(Lexer):
|
|||||||
lexer = Lambda_lexer()
|
lexer = Lambda_lexer()
|
||||||
|
|
||||||
class Lambda_parser(Parser):
|
class Lambda_parser(Parser):
|
||||||
|
''' Grammaire décrivant les λ-termes
|
||||||
|
term : VAR
|
||||||
|
| LAMBDA VAR POINT term
|
||||||
|
| LPAR term term RPAR
|
||||||
|
'''
|
||||||
tokens = Lambda_lexer.tokens
|
tokens = Lambda_lexer.tokens
|
||||||
|
|
||||||
|
# @_('VAR')
|
||||||
|
# def term(self, p):
|
||||||
|
# return Lambda_terme(0, p[0])
|
||||||
|
|
||||||
|
# @_('LAMBDA VAR POINT term')
|
||||||
|
# def term(self, p):
|
||||||
|
# return Lambda_terme(1, p[1], p.term)
|
||||||
|
|
||||||
|
# @_('LPAR term term RPAR')
|
||||||
|
# def term(self, p):
|
||||||
|
# return Lambda_terme(2, p.term0, p.term1)
|
||||||
|
|
||||||
@_('VAR')
|
@_('VAR')
|
||||||
def term(self, p):
|
def term(self, p):
|
||||||
return Lambda_terme(0, p[0])
|
return (0, p[0])
|
||||||
|
|
||||||
@_('LAMBDA VAR POINT term')
|
@_('LAMBDA VAR POINT term')
|
||||||
def term(self, p):
|
def term(self, p):
|
||||||
return Lambda_terme(1, p[1], p.term)
|
return (1, p[1], p.term)
|
||||||
|
|
||||||
@_('LPAR term term RPAR')
|
@_('LPAR term term RPAR')
|
||||||
def term(self, p):
|
def term(self, p):
|
||||||
return Lambda_terme(2, p.term0, p.term1)
|
return (2, p.term0, p.term1)
|
||||||
|
|
||||||
|
|
||||||
parser = Lambda_parser()
|
parser = Lambda_parser()
|
||||||
|
|
||||||
@ -80,27 +99,104 @@ class Lambda_termeError(Exception):
|
|||||||
self.message = msg
|
self.message = msg
|
||||||
|
|
||||||
class Lambda_terme():
|
class Lambda_terme():
|
||||||
def __init__(self, categorie, *args):
|
'''
|
||||||
|
Création de λ-terme
|
||||||
|
|
||||||
|
>>> T1 = Lambda_terme('z')
|
||||||
|
>>> print(T1)
|
||||||
|
z
|
||||||
|
>>> T2 = Lambda_terme('!x.(y x)')
|
||||||
|
>>> print(T2)
|
||||||
|
λx.(y x)
|
||||||
|
>>> T3 = Lambda_terme('(!x.(y x) z)')
|
||||||
|
>>> print(T3)
|
||||||
|
(λx.(y x) z)
|
||||||
|
|
||||||
|
Quelques prédicats
|
||||||
|
>>> [(t.est_variable(), t.est_abstraction(), t.est_application()) for t in (T1, T2, T3)]
|
||||||
|
[(True, False, False), (False, True, False), (False, False, True)]
|
||||||
|
|
||||||
|
Abstraction d'un terme
|
||||||
|
>>> T4 = T3.abstrait('z')
|
||||||
|
>>> print(T4)
|
||||||
|
λz.(λx.(y x) z)
|
||||||
|
|
||||||
|
Application d'un terme sur un autre
|
||||||
|
>>> T5 = T4.applique(Lambda_terme('t'))
|
||||||
|
>>> print(T5)
|
||||||
|
(λz.(λx.(y x) z) t)
|
||||||
|
|
||||||
|
Autres prédicats
|
||||||
|
>>> [(t.est_redex(), t.est_forme_normale()) for t in (T1, T2, T3, T4, T5)]
|
||||||
|
[(False, True), (False, True), (True, False), (False, False), (True, False)]
|
||||||
|
|
||||||
|
Calcul de forme normale
|
||||||
|
|
||||||
|
>>> print(T5.forme_normale())
|
||||||
|
(y t)
|
||||||
|
>>> print(T5.forme_normale(verbose=True))
|
||||||
|
(λz.(λx.(y x) z) t)
|
||||||
|
1: ---> (λz.(λx.(y x) z) t)
|
||||||
|
2: ---> (λx.(y x) t)
|
||||||
|
3: ---> (y t)
|
||||||
|
Forme normale calculée : (y t)
|
||||||
|
(y t)
|
||||||
|
>>> OMEGA = Lambda_terme('(!x.(x x) !x.(x x))')
|
||||||
|
>>> print(OMEGA.forme_normale(verbose=True, nb_etapes_max=10))
|
||||||
|
(λx.(x x) λx.(x x))
|
||||||
|
1: ---> (λx.(x x) λx.(x x))
|
||||||
|
2: ---> (λx.(x x) λx.(x x))
|
||||||
|
3: ---> (λx.(x x) λx.(x x))
|
||||||
|
4: ---> (λx.(x x) λx.(x x))
|
||||||
|
5: ---> (λx.(x x) λx.(x x))
|
||||||
|
6: ---> (λx.(x x) λx.(x x))
|
||||||
|
7: ---> (λx.(x x) λx.(x x))
|
||||||
|
8: ---> (λx.(x x) λx.(x x))
|
||||||
|
9: ---> (λx.(x x) λx.(x x))
|
||||||
|
10: ---> (λx.(x x) λx.(x x))
|
||||||
|
Pas de forme normale atteinte après 10 étapes de réduction
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
def __init__(self, *args):
|
||||||
|
nb_args = len(args)
|
||||||
|
if nb_args not in (1, 2, 3):
|
||||||
|
raise Lambda_termeError('Lambda_terme : Nbre arguments incorrect')
|
||||||
|
if nb_args == 1:
|
||||||
|
if not isinstance(args[0], str):
|
||||||
|
raise Lambda_termeError('Lambda_terme : type argument incorrect')
|
||||||
|
self._content = Lambda_terme._cree(parser.parse(lexer.tokenize(args[0])))
|
||||||
|
else:
|
||||||
|
categorie = args[0]
|
||||||
if categorie not in (0, 1, 2):
|
if categorie not in (0, 1, 2):
|
||||||
raise Lambda_termeError('categorie non valide')
|
raise Lambda_termeError('categorie non valide')
|
||||||
if categorie == 0:
|
if categorie == 0:
|
||||||
if len(args) != 1 or not isinstance(args[0], str):
|
if nb_args != 2 or not isinstance(args[1], str):
|
||||||
raise Lambda_termeError('mauvaise construction pour une variable')
|
raise Lambda_termeError('mauvaise construction pour une variable')
|
||||||
|
self._content = tuple(args)
|
||||||
elif categorie == 1:
|
elif categorie == 1:
|
||||||
if (len(args) != 2 or
|
if (nb_args != 3 or
|
||||||
not isinstance(args[0], str) or
|
not isinstance(args[1], str) or
|
||||||
not isinstance(args[1], Lambda_terme)):
|
not (isinstance(args[2], tuple) or isinstance(args[2], Lambda_terme))):
|
||||||
raise Lambda_termeError('mauvaise construction pour une abstraction')
|
raise Lambda_termeError('mauvaise construction pour une abstraction')
|
||||||
|
self._content = (1, args[1],
|
||||||
|
Lambda_terme(*args[2]) if isinstance(args[2], tuple) else args[2])
|
||||||
else:
|
else:
|
||||||
if (len(args) != 2 or
|
if (nb_args != 3 or
|
||||||
not isinstance(args[0], Lambda_terme) or
|
not (isinstance(args[1], tuple) or isinstance(args[1], Lambda_terme)) or
|
||||||
not isinstance(args[1], Lambda_terme)):
|
not (isinstance(args[2], tuple) or isinstance(args[2], Lambda_terme))):
|
||||||
raise Lambda_termeError('mauvaise construction pour une application')
|
raise Lambda_termeError('mauvaise construction pour une application')
|
||||||
self._content = (categorie,) + tuple(args)
|
self._content = (2,
|
||||||
|
Lambda_terme(*args[1]) if isinstance(args[1], tuple) else args[1],
|
||||||
|
Lambda_terme(*args[2]) if isinstance(args[2], tuple) else args[2])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def cree(descr):
|
def _cree(descr):
|
||||||
return parser.parse(lexer.tokenize(descr))
|
if descr[0] == 0:
|
||||||
|
return descr
|
||||||
|
elif descr[0] == 1:
|
||||||
|
return (1, descr[1], Lambda_terme(*descr[2]))
|
||||||
|
else:
|
||||||
|
return (2, Lambda_terme(*descr[1]), Lambda_terme(*descr[2]))
|
||||||
|
|
||||||
def est_variable(self):
|
def est_variable(self):
|
||||||
return self._content[0] == 0
|
return self._content[0] == 0
|
||||||
@ -111,6 +207,15 @@ class Lambda_terme():
|
|||||||
def est_application(self):
|
def est_application(self):
|
||||||
return self._content[0] == 2
|
return self._content[0] == 2
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.est_variable():
|
||||||
|
return self._content[1]
|
||||||
|
elif self.est_abstraction():
|
||||||
|
return 'λ{:s}.{:s}'.format(self._content[1], str(self._content[2]))
|
||||||
|
else:
|
||||||
|
return '({:s} {:s})'.format(str(self._content[1]), str(self._content[2]))
|
||||||
|
|
||||||
|
|
||||||
def applique(self, terme):
|
def applique(self, terme):
|
||||||
if not isinstance(terme, Lambda_terme):
|
if not isinstance(terme, Lambda_terme):
|
||||||
raise Lambda_termeError('Application impossible')
|
raise Lambda_termeError('Application impossible')
|
||||||
@ -203,17 +308,27 @@ class Lambda_terme():
|
|||||||
def reduit(self):
|
def reduit(self):
|
||||||
return self._reduit()
|
return self._reduit()
|
||||||
|
|
||||||
def __str__(self):
|
def forme_normale(self, nb_etapes_max=100, verbose=False):
|
||||||
if self.est_variable():
|
lambda_terme = self
|
||||||
return self._content[1]
|
etape = 0
|
||||||
elif self.est_abstraction():
|
forme_normale_atteinte = False
|
||||||
return 'λ{:s}.{:s}'.format(self._content[1], str(self._content[2]))
|
if verbose: print(lambda_terme)
|
||||||
|
while not forme_normale_atteinte and etape < nb_etapes_max:
|
||||||
|
etape += 1
|
||||||
|
terme_reduit, est_reduit = lambda_terme.reduit()
|
||||||
|
if verbose: print('{:3d}: ---> {:s}'.format(etape, str(lambda_terme), str(terme_reduit)))
|
||||||
|
forme_normale_atteinte = not est_reduit
|
||||||
|
lambda_terme = terme_reduit
|
||||||
|
if forme_normale_atteinte:
|
||||||
|
if verbose: print('Forme normale calculée : {:s}'.format(str(terme_reduit)))
|
||||||
|
return terme_reduit
|
||||||
else:
|
else:
|
||||||
return '({:s} {:s})'.format(str(self._content[1]), str(self._content[2]))
|
if verbose: print('Pas de forme normale atteinte après {:d} étapes de réduction'.format(etape))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import doctest
|
import doctest
|
||||||
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS, verbose=False)
|
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS, verbose=True)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user