import match
import copy
##La variable globale utilsee pour signifier un ECHEC
echec='ECHEC'
##Base des faits
##Syntax des faits [['fait1'....],...,['faitn']]
faits = []
##Base des regles
## Syntaxe d'une regles [['condition1',...,'conditionn'],'consequence']
regles = []
## initialise les 2 bases
def initDBs():
videFaits()
videRegles()
## FAITS
## vide la base des faits
##faits[:] iter sur tous les elements de faits
def videFaits():
del faits[:]
## affiche la base des faits
def afficheFaits():
for x in faits:
print x
## Ajoute un fait a la base des faits <=> pas deja present dans faits
## @param fait un fait SOUS form d'une liste []
def ajouteFait(fait):
faits.append(fait)
#################################################################################
## REGLES
## vide la base des regles
##faits[:] iter sur tous les elements de faits
def videRegles():
del regles[:]
#########################################################
## affiche la base des faits
def afficheRegles():
for x in regles:
print x
#########################################################
## Ajoute une regles a la base des regles
## @param regle ajoute le regle a liste
def ajouteRegle(regle):
regles.append(regle)
## retourne les conditions d'une regle
## @param regle la regle
## @ret la condition de la regle (regle[0])
def conditionsRegle(regle):
return regle[0]
## retourne la consequence d'une regle
## @param regle la regle
## @ret la consequence de la regle (regle[1])
def consequenceRegle(regle):
return regle[1]
## verifie que le fait verifie le liste de conditions d'une regle
## et retourne la liste d'environemnt reuissie due au substituions ET la liste des conditions restante non verifier par fait
## @param fait le fait ['a', ...,'b']
## @pram conditions les condition d'une regle ['cond1',....,'condn']
## @ret [[{environement1}, ...,{environementn}],[[cond_restant_1_1,...,cond_restant_1_k]],[cond_restant_n_1,...,cond_restant_n_k]]]
def faitSatisfaitUneCondition(fait, conditions):
envs = []
rests = []
for c in conditions:
rc = match.match(fait, c)
if rc != echec:
envs.append(rc)
rl = conditions[:]
rl.remove(c)
rests.append(rl)
return [envs, rests]
## verife la validite de la condition en esseyant toues les substituions par les faits de la base
## @param condition la condition a verifier
## @param liste_environements [{...},...,{...}]
## @param faitsDB la liste des faits [[],...,[]]
## @ret la liste des environement possibles [{},...,{}], vide si aucun
def satisfaitUneCondition (condition, listeEnvironements):
r = []
for f in faits:
for e in listeEnvironements:
rc = match.match(f, condition, e)
#if rc == echec:
# rc = {}
# XXX: personal idea
if rc != echec:
r.append(rc)
return r
## Verifie qu'une liste de conditions peut etre verifier par les environements existants
## @param conditions la liste de condition a verifier [[],...,[]]
## @param environement {...}
## @param faitsDB la liste des faits [[],...,[]]
## @ret la liste des environement possibles [{},...,{}]; [] si aucun
def satisfaitConditions(conditions,environement):
envlist = [environement]
for c in conditions:
if envlist == []:
return envlist
envlist = satisfaitUneCondition(c, envlist)
return envlist
## instantie la consequence d'une regle et retourne une liste de nouveau fait par environemt
## @param proposition la proposition
## @param listeEnvironements la liste des environements [{},....,{}]
## @ret une liste de nouveau faits ['fait1',...,'fait2']
def instantieVariables(proposition, listeEnvironements):
r = []
for e in listeEnvironements:
r.append(match.substitueVariables(proposition, e))
return r
## fait le chainage avant avec filtrage
## @param regles les regles a verifer
## @param faits_initiaux les faits initiaux
## @ret la liste des faits deduits
def chainageAvantAvecFiltrage(regles, faits_initiaux):
Q = copy.deepcopy(faits)
while Q:
q = Q.pop(0)
if q not in faits:
ajouteFait(q)
print q
for r in regles:
c = conditionsRegle(r)
res = faitSatisfaitUneCondition(q, c)
for env, cond in zip(res[0], res[1]):
e2 = satisfaitConditions(cond, env)
ns = instantieVariables(consequenceRegle(r), e2)
for n in ns:
if n not in faits:
Q.append(n)
#execfile("testFaitSatisfaitUneCondition.py")
#execfile("testSatisfaitUneCondition.py")
#execfile("testSatisfaitConditions.py")
#execfile("testInstantieVariables.py")
execfile("impots2.py")
chainageAvantAvecFiltrage(regles,faits)