def has_value(connector):
    return connector("has_value")

def get_value(connector):
    return connector("value")

def set_value(connector, new_value, informant):
    return connector("set_value")(new_value, informant)

def forget_value(connector, retractor):
    return connector("forget")(retractor)

def connect(connector, new_constraint):
    return connector("connect")(new_constraint)
def multiplier(m1, m2, product):
    def process_new_value():
        if ((has_value(m1) and get_value(m1) == 0)
                or (has_value(m2) and get_value(m2) == 0)):
            set_value(product, 0, me)
        elif has_value(m1) and has_value(m2):
            set_value(product, get_value(m1) * get_value(m2), me)
        elif has_value(product) and has_value(m1):
            set_value(m2, get_value(product) / get_value(m1), me)
        elif has_value(product) and has_value(m2):
            set_value(m1, get_value(product) / get_value(m2), me)
        else:
            pass
    def process_forget_value():
        forget_value(product, me)
        forget_value(m1, me)
        forget_value(m2, me)
        process_new_value()
    def me(request):
        if request == "I have a value.":
            process_new_value()
        elif request == "I lost my value.":
            process_forget_value()
        else:
            error("unknown request -- multiplier", request)
    connect(m1, me)
    connect(m2, me)
    connect(product, me)
    return me
