In [1]:
import pywrapfst as fst
import os
from IPython.display import Image,display

alpha = fst.SymbolTable()
alpha.add_symbol('<eps>')
for ch in 'abcdefghijklmnopqrstuvwxyzéàèâêôîûëüç0123456789_':
    alpha.add_symbol(ch)

comp = fst.Compiler(isymbols = alpha, osymbols=alpha, keep_isymbols=True,
                    keep_osymbols=True, acceptor=True)

def compile_ens_fini(comp,lst):
    comp.compile()
    res = comp.compile()
    res.add_state()
    res.set_start(0)
    res.add_state()
    res.set_final(1)
    for st in lst:
        if len(st) == 1:
            res.add_arc(0,fst.Arc(alpha.find(st[0]),alpha.find(st[0]),0,1))
        elif len(st) == 0:
            res.set_final(0)
        else:
            n = res.add_state()
            res.add_arc(0,fst.Arc(alpha.find(st[0]),alpha.find(st[0]),0,n))
            for ch in st[1:-1]:
                prev = n
                n = res.add_state()
                sym = alpha.find(ch)
                res.add_arc(prev,fst.Arc(sym,sym,0,n))
            res.add_arc(n,fst.Arc(alpha.find(st[-1]),alpha.find(st[-1]),0,1))
    res = fst.determinize(res)
    res.minimize()
    return res

def my_concat(lst):
    res = lst[0].copy()
    for auto in lst[1:]:
        res.concat(auto)
    res.rmepsilon()
    res = fst.determinize(res)
    res.minimize()
    return res

def my_union(lst):
    res = lst[0].copy()
    for auto in lst[1:]:
        res.union(auto)
    res.rmepsilon()
    res = fst.determinize(res)
    res.minimize()
    return res
    
def display_auto(auto):
    auto.draw('tmp_auto.dot', portrait=True, acceptor=True)
    os.system('/usr/bin/dot -Tpng tmp_auto.dot > tmp_auto.png')
    display(Image(filename='tmp_auto.png',width=500))
           
            
In [2]:
mois = compile_ens_fini(comp,['janvier','février','mars','avril',
                              'mai','juin','juillet','août','septembre',
                              'octobre','novembre','décembre'])
display_auto(mois)
No description has been provided for this image
In [3]:
jour = compile_ens_fini(comp,[str(i) for i in range(1,32)])
display_auto(jour)
No description has been provided for this image
In [4]:
premier_chiffre= compile_ens_fini(comp,["1","2"])
chiffre = compile_ens_fini(comp,[str(i) for i in range(0,10)])

annee = my_concat([premier_chiffre,chiffre,chiffre,chiffre])
display_auto(annee)
No description has been provided for this image
In [5]:
espace = compile_ens_fini(comp,['_'])

date_approximative = my_concat([jour,espace,mois,espace,annee])
display_auto(date_approximative)
No description has been provided for this image
In [6]:
lst_divis = []
for i in range(1,100):
    if i % 4 == 0:
        if i<10:
            lst_divis.append('0'+str(i))
        else:
            lst_divis.append(str(i))


divisible_par_4 = compile_ens_fini(comp,lst_divis)
display_auto(divisible_par_4)
annee_bissextile_4 = my_concat([premier_chiffre,chiffre,divisible_par_4])
zerozero = compile_ens_fini(comp,["00"])
nombre_div_400 = my_concat([divisible_par_4,zerozero])
annee_div_400 = fst.intersect(annee,nombre_div_400)
display_auto(annee_div_400)
annee_bissextile = my_union([annee_bissextile_4,annee_div_400])
display_auto(annee_bissextile)
annee_pas_bissextile = fst.difference(annee,annee_bissextile)
display_auto(annee_pas_bissextile)
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [7]:
mois_sans_31 = compile_ens_fini(comp,['février','avril','juin','septembre',
                              'novembre'])
j31 = compile_ens_fini(comp,['31'])
j30fev = compile_ens_fini(comp,['30_février_'])
j29fev = compile_ens_fini(comp,['29_février_'])
faux_31 = my_concat([j31,espace,mois_sans_31,espace,annee])
faux_30 = my_concat([j30fev,annee])
faux_29 = my_concat([j29fev,annee_pas_bissextile])

date_fausse = my_union([faux_31,faux_30,faux_29])
display_auto(date_fausse)
No description has been provided for this image
In [8]:
date_correcte = fst.difference(date_approximative,date_fausse)
print('taille (nb états) de date_correcte',date_correcte.num_states())
taille (nb états) de date_correcte 74
In [9]:
def teste_date(date):
    auto = compile_ens_fini(comp,[date])
    inter = fst.intersect(auto,date_correcte)
    return inter.num_states() > 0


print(teste_date('grgr'))
print(teste_date('1_janvier_2013'))
print(teste_date('29_février_2013'))
print(teste_date('29_février_2016'))
print(teste_date('29_février_2000'))
False
True
False
True
True