Module src.olaaaf.domainKnowledge.conversionKnowledge
Class representing conversion knowledges.
Classes
class ConversionKnowledge-
Class representing conversion knowledges, i.e. knowledges linking two numerical variables.
Expand source code
class ConversionKnowledge(DomainKnowledge): """ Class representing conversion knowledges, i.e. knowledges linking two numerical variables. """ __unitsConversion: dict[Variable, dict[Variable, Fraction]] def __init__(self) -> None: self.__unitsConversion = {} def addConversion(self, src: tuple[Variable, Fraction], trgt: tuple[Variable, Fraction]): """ Adds a new conversion to the conversion knowledge. For exemple, the conversion 1*banana_kg = 1000*banana_g could be added with the following call: knowledge.addConversion((banana_kg, Fraction(1)), (banana_g, Fraction(1000))) Parameters ---------- src: `tuple[Variable, Fraction]` The source of the conversion, with a given coefficent. trgt: `tuple[Variable, Fraction]` The target of the conversion, with a given coefficent. """ src_var, src_coef = src trgt_var, trgt_coef = trgt if self.__unitsConversion.get(src_var) is None: self.__unitsConversion[src_var] = dict() self.__unitsConversion[src_var][trgt_var] = trgt_coef/src_coef if self.__unitsConversion.get(trgt_var) is None: self.__unitsConversion[trgt_var] = dict() self.__unitsConversion[trgt_var][src_var] = src_coef/trgt_coef def addConversions(self, conversions: list[tuple[tuple[Variable, Fraction], tuple[Variable, Fraction]]]): """ Adds new conversions to the conversion knowledge. Parameters ---------- conversions: `list[tuple[tuple[Variable, Fraction], tuple[Variable, Fraction]]]` The new conversions. """ for conv in conversions: self.addConversion(*conv) def removeConversion(self, src: Variable, trgt: Variable): """ Removes a conversion from the conversion knowledge. Parameters ---------- src: `olaaaf.formula.formula.Variable` The source of the conversion. trgt: `olaaaf.formula.formula.Variable` The target of the conversion. """ if (self.__unitsConversion.get(src) is not None) and (self.__unitsConversion[src].get(trgt) is not None): del self.__unitsConversion[src][trgt] if len(self.__unitsConversion[src]) == 0: del self.__unitsConversion[src] if (self.__unitsConversion.get(trgt) is not None) and (self.__unitsConversion[trgt].get(src) is not None): del self.__unitsConversion[trgt][src] if len(self.__unitsConversion[trgt]) == 0: del self.__unitsConversion[trgt] def getConversions(self): """ Returns the conversions. Returns ------- `dict[Variable, dict[Variable, Fraction]]` The conversions. """ return self.__unitsConversion def toConstraints(self): """ Converts the domain knowledge object to constraints. Returns ------- `olaaaf.formula.formula.Formula` The formula representing the domain knowledges. """ copyCk = self.copy() fmSet = set() while len(copyCk.__unitsConversion) != 0: leftVar, unitConversions = copyCk.__unitsConversion.popitem() for rightVar, coef in unitConversions.items(): lc = LinearConstraint("") lc.variables[rightVar] = Fraction(1) lc.variables[leftVar] = -coef lc.operator = ConstraintOperator.EQ lc.bound = 0 fmSet.add(lc) copyCk.removeConversion(leftVar, rightVar) return And(*fmSet) def inferFrom(self, psi: Formula): """ Infer new knowledges from a given formula using the domain knowledges. Parameters ---------- psi: `olaaaf.formula.formula.Formula` The formula to infer from. Returns ------- `olaaaf.formula.formula.Formula` The inferred formula. """ inferedChildren = set() knownVariables = set() if isinstance(psi, And): for c in psi.children: inferedChildren |= (self.__inferFromLc(c, knownVariables)) elif isinstance(psi, LinearConstraint): inferedChildren |= (self.__inferFromLc(psi, knownVariables)) if len(inferedChildren) != 0: return psi & And(*inferedChildren) return psi def __inferFromLc(self, psi: LinearConstraint, knownVariables: set[Variable]): inferedChildren = set() if isinstance(psi, LinearConstraint) and (len(psi.variables) == 1) and (psi.operator == ConstraintOperator.EQ): lcVar = list(psi.variables.keys())[0] knownVariables.add(lcVar) toDoVariables = {(lcVar, 1)} while len(toDoVariables) != 0: (toDoVar, toDoCoef) = toDoVariables.pop() if self.__unitsConversion.get(toDoVar) is None: continue for var, coef in self.__unitsConversion[toDoVar].items(): if (var not in knownVariables): lc = LinearConstraint("") lc.variables[var] = Fraction(1) lc.operator = ConstraintOperator.EQ lc.bound = psi.bound * coef*toDoCoef inferedChildren.add(lc) knownVariables.add(var) toDoVariables.add((var, coef*toDoCoef)) return inferedChildren def copy(self): from copy import deepcopy copy = ConversionKnowledge() copy.__unitsConversion = deepcopy(self.__unitsConversion) return copyAncestors
- DomainKnowledge
- abc.ABC
Methods
def addConversion(self, src: tuple[Variable, fractions.Fraction], trgt: tuple[Variable, fractions.Fraction])-
Adds a new conversion to the conversion knowledge. For exemple, the conversion 1banana_kg = 1000banana_g could be added with the following call:
knowledge.addConversion((banana_kg, Fraction(1)), (banana_g, Fraction(1000)))Parameters
src:tuple[Variable, Fraction]- The source of the conversion, with a given coefficent.
trgt:tuple[Variable, Fraction]- The target of the conversion, with a given coefficent.
def addConversions(self, conversions: list[tuple[tuple[Variable, fractions.Fraction], tuple[Variable, fractions.Fraction]]])-
Adds new conversions to the conversion knowledge.
Parameters
conversions:list[tuple[tuple[Variable, Fraction], tuple[Variable, Fraction]]]- The new conversions.
def copy(self)def getConversions(self)-
Returns the conversions.
Returns
dict[Variable, dict[Variable, Fraction]]The conversions. def removeConversion(self, src: Variable, trgt: Variable)-
Removes a conversion from the conversion knowledge.
Parameters
src:olaaaf.formula.formula.Variable- The source of the conversion.
trgt:olaaaf.formula.formula.Variable- The target of the conversion.
Inherited members