'''MODULE d'implémentation de type abstrait PILE IMMUABLE
   en utilisant des Cellules TUPLES pour former une liste chaînée
 
La Pile vide sera représentée par un tuple vide ().
Le sommet d'une Pile non vide est situé du même côté que la tête de la liste chaînée associée.
 
Fonctions primitives
--------------------
CST : nouvelle_pile() -> 'Pile'
CST : est_pile_vide(p:'Pile') -> bool
CST : empiler(p:'Pile', elt:'Element') -> 'Pile'
CST : depiler(p:'Pile NON VIDE') -> 'Pile'
CST : lire_sommet(p:'Pile NON VIDE') -> 'Element'
 
'''
 
def nouvelle_pile() -> 'Pile':
    '''Renvoie une nouvelle Pile vide'''
    return ()
 
def est_pile_vide(p:'Pile') -> bool:
    '''Prédicat qui renvoie True si p est une Pile vide'''
    return p == ()
 
def empiler(p:'Pile', elt:'Element' ) -> 'Pile':
    '''Renvoie une pile basée sur p mais en rajoutant elt au sommet'''
    return (elt, p)                               # renvoie un tuple contenant elt et menant ensuite à la pile p reçue
 
def depiler(p:'Pile NON VIDE') -> 'Pile':
    '''Renvoie une pile basée sur p mais en supprimant le sommet'''
    return p[1]                                   # renvoie un tuple qui est le reste de la pile p
 
def lire_sommet(p:'Pile NON VIDE') -> 'Element':
    '''Renvoie la valeur actuellement au sommet de la Pile p NON VIDE'''
    return p[0]                                   # renvoie la valeur stockée dans la cellule Sommet
 
 
 
if __name__ == '__main__':
    a = nouvelle_pile()
    a = empiler(a, 0)
    a = empiler(a, 5)
    a = empiler(a, 10)
    a = empiler(a, 15)
     
    s = lire_sommet(a)
    assert s == 15
     
    a = depiler(a)
    s = lire_sommet(a)
    assert s == 10