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)
In [3]:
jour = compile_ens_fini(comp,[str(i) for i in range(1,32)])
display_auto(jour)
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)
In [5]:
espace = compile_ens_fini(comp,['_'])
date_approximative = my_concat([jour,espace,mois,espace,annee])
display_auto(date_approximative)
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)
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)
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