Newer
Older
ai / lab6 / libPSC.py
@Andreas Jaggi Andreas Jaggi on 8 May 2006 7 KB Did Lab 6a, with a sudoku :-)
#################################################################################
print "Chargement du module variable et noeud pour PSC"
#################################################################################
import copy

##contient le nombre de contraintes visitees
NBCONTRAINTE=0

##Classe modelisant une Variable
class Variable:

	##Constructeur de la classe variable
	##INITIALISE valeur = -1
	##@param nom le nom de la variable; sert d'identifiant
	##@param domaine le domaine de valeur sous fourme []
	def __init__(self, nom, domaine):
		self.nom=nom
		self.domaine=domaine
		self.valeur=-1
		self.label=[]
		self.initLabel()

	
	##reinitialise le contenu de l'attribut label
	def initLabel(self):
		self.label=copy.deepcopy(self.domaine)

	##efface du label la valeur d et stock d dans self.efface
	##@param d la veleur de domaine
	def enleveDuLabel(self,d):
		if d in self.label:
			self.label.remove(d)

	##met a jour le label
	##@param label le nouveau label
	def metAJourValeur(self,label):
		self.label=label 
		
	##met a jour la valeur
	##@param valeur la nouvelle valeur
	def metAJourValeur(self,valeur):
		self.valeur=valeur   

	##Verifie que le nom est egalle a celui passe en parametre
	##@param nom un nom a verifier
	##@ret true <=>self.nom=nom
	def nomEstEgalle(self,nom):
		return self.nom==nom
		
	## retourne la taille du domaine
	def tailleDuDomaine(self):
		return len(self.domaine)
	
	## retourne true <=> le domaine est vide
	def domaineEstVide(self):
		self.tailleDuDomaine()==0;

	##retourne une representation en String de la Variable
	def __str__(self):
		str = "var : < %s , %s >" %(self.nom, self.domaine)
		return str

##class Contrainte:
class Contrainte:

	##constructeur
	##@param depart la variable de depart
	##@param arrive la variable d'arrive
	def __init__(self,depart,arrive):
		self.depart=depart
		self.arrive=arrive

	##retournce la dimension
	def dimension(self):
		return 0

	## verifie que la valeur de la variable 1 et 2 sont valide avec la contrainte
	## @return true <=> valide
	def estValide(self):
		print "coucou"

	##retourne une representation en String de la contrainte
	def __str__(self):
		str = "contrainte : < %s , %s >" %(self.depart.nom, self.arrive.nom)
		return str		

##Classe modelisant une contraite unaire
class ContrainteUnaire(Contrainte):

	##constructeur
	##@param ref valeur de reference
	##@param op "<" || "<="
	##@param refVar reference sur la variable
	def __init__(self,refVar,op,ref):
		Contrainte.__init__(self,refVar,refVar)
		self.ref=ref
		self.op=op
		self.refVar=refVar

	##retournce la dimension
	def dimension(self):
		return 1

	## verifie que la valeur de la variable est valide avec la contrainte
	## @param valeur la valeur a verifier
	## @return true <=> valide
	def estValide(self):
		global NBCONTRAINTE
		NBCONTRAINTE+=1
		if (self.op=="<"):
			return self.refVar.valeur<self.ref
		elif (self.op=="<="):
			return self.refVar.valeur<=self.ref
		else:
			print "|-| Operateur", self.op, "non implemente"
			return false
		
	##retourne une representation en String de la contrainte
	def __str__(self):
		str = "contrainte : < %s , %s , %s >" %(self.refVar.nom, self.op, self.ref)
		return str

##Classe modelisant une contraite binaire
class ContrainteBinaire(Contrainte):

	##constructeur
	##@param op "<>" || "=="
	##@param refVar1 reference sur la variable 1
	##@param refVar2 reference sur la variable 2
	def __init__(self,refVar1,op,refVar2):
		Contrainte.__init__(self,refVar1,refVar2)
		self.refVar1=refVar1
		self.op=op
		self.refVar2=refVar2

	##retournce la dimension
	def dimension(self):
		return 2	

	## verifie que la valeur de la variable 1 et 2 sont valide avec la contrainte
	## @return true <=> valide
	def estValide(self):
		global NBCONTRAINTE
		NBCONTRAINTE+=1
		if (self.op=="<>"):
			return self.refVar1.valeur<>self.refVar2.valeur
		elif (self.op=="=="):
			return self.refVar1.valeur==self.refVar2.valeur
		else:
			print "|-| Operateur", self.op, "non implemente"
			return false

	## verifie que si la valeur de la variable 1 , alors la contrainte n'es pas violee
	## @return true <=> possible
	def estPossible(self):
		global NBCONTRAINTE
		uneVraie = lambda x, y :  x or y
		results=[]
		if len(self.refVar2.domaine)==0 :
			return False
		for d in self.refVar2.domaine:
			NBCONTRAINTE+=1
			self.refVar2.metAJourValeur(d)
			if (self.op=="<>"):
				results.append(self.refVar1.valeur<>self.refVar2.valeur)
			elif (self.op=="=="):
				results.append(self.refVar1.valeur==self.refVar2.valeur)
			else:
				print "|-| Operateur", self.op, "non implemente"
				results.append(false)
		return reduce(uneVraie,results)

	## verifie que si la valeur de la variable 1 , alors la contrainte n'es pas violee
	## @return true <=> possible
	def estPossibleAvecLabel(self):
		global NBCONTRAINTE
		uneVraie = lambda x, y :  x or y
		results=[]
		if len(self.refVar2.label)==0:
			return False
		for d in self.refVar2.label:
			NBCONTRAINTE+=1
			self.refVar2.metAJourValeur(d)
			if (self.op=="<>"):
				results.append(self.refVar1.valeur<>self.refVar2.valeur)
			elif (self.op=="=="):
				results.append(self.refVar1.valeur==self.refVar2.valeur)
			else:
				print "|-| Operateur", self.op, "non implemente"
				results.append(false)
		return reduce(uneVraie,results)	

	##retourne une representation en String de la contrainte
	def __str__(self):
		str = "contrainte : < %s , %s , %s >" %(self.refVar1.nom, self.op, self.refVar2.nom)
		return str		

##Classe modelisant un Noeud
class Noeud:

	##constructeur
	##l'attribut pos est initialise a 0
	##@param variable la variable referencee
	def __init__(self,variable):
		self.refVar=variable

	##compare deux noeuds par rapport à leur taille de domaine
	def __cmp__(self,n2):
		a = len(self.refVar.domaine)
		b = len(n2.refVar.domaine)
		if a == b:
			return 0
		if a < b:
			return -1
		if a > b:
			return 1

	##fait la consistance du noeud
	##@param contraintes la liste de contraintes unaires pour ce noeud
	def consistanceDuNoeud(self,contraintes):
		for x in self.refVar.domaine[:]:
			self.refVar.metAJourValeur(x)
			for c in contraintes:
				if not c.estValide():
					self.refVar.domaine.remove(x)
					break
	


	##retourne une representation en String de la Variable
	def __str__(self):
		str = "Noeud -> %s " %(self.refVar)
		return str

##classe modelisant un arc
class Arc:

	##constructeur
	##@param contrainte la contrainte referencee
	def __init__(self,contrainte):
		self.refContrainte=contrainte

	##revise la consistance des valeurs de domaine pour la contrainte representee par cet arc
	def reviser(self):
		modified = False

		for x in self.refContrainte.refVar1.domaine[:]:
			self.refContrainte.refVar1.metAJourValeur(x)

			if not self.refContrainte.estPossible():
				modified = True
				self.refContrainte.refVar1.domaine.remove(x)

		return modified
	
	##retourne une representation en String de l'arc
	def __str__(self):
		str = "Arc -> %s " %(self.refContrainte)
		return str