[docs]classAbstractPropagator:def__call__(self,child:MessageNode):"""Calling this method would propagte the feedback from the child to the parents."""assertisinstance(child,MessageNode)assertall([len(f)<=1forfinchild.feedback.values()])# All MessageNode feedback should be at most length 1propagated_feedback=self.propagate(child)# Check propagated feedback has the right format# It should be a dictionary with the parents as keys and the feedback as valuesassertisinstance(propagated_feedback,dict)assertall((pinpropagated_feedbackforpinchild.parents))returnpropagated_feedback
[docs]defpropagate(self,child:MessageNode)->Dict[Node,Any]:"""Compute propagated feedback to node.parents of a node. Return a dict where the keys are the parents and the values are the propagated feedback. """raiseNotImplementedError
[docs]classAbstractFeedback:"""Feedback container used by propagators. It needs to support addition."""def__add__(self,other):raiseNotImplementedErrordef__radd__(self,other):ifother==0:# for support sumreturnselfelse:returnself.__add__(other)
[docs]definit_feedback(self,node:Node,feedback:Any):""" Given raw feedback, create the feedback object that will be propagated recursively. """raiseNotImplementedError
def_propagate(self,child:MessageNode)->Dict[Node,Any]:"""Compute propagated feedback to node.parents based on node.description, node.data, and node.feedback. Return a dict where the keys are the parents and the values are the propagated feedback. """raiseNotImplementedError
# Note:# if len(feedback) > 1, it means there are two or more child nodes from this node,# we might need to perform a "merge" feedback action# # TODO test
def_propagate(self,child:MessageNode):if"user"inchild.feedback:assertlen(child.feedback)==1,"user feedback should be the only feedback"assertlen(child.feedback["user"])==1feedback=child.feedback["user"][0]else:# Simply sum the feedbackfeedback_list=[v[0]fork,vinchild.feedback.items()]assertlen(feedback_list)>0assertall([type(feedback_list[0])istype(f)forfinfeedback_list]),"error in propagate"ifisinstance(feedback_list[0],str):feedback="".join(feedback_list)else:feedback=sum(feedback_list)return{parent:feedbackforparentinchild.parents}