Beispiel #1
0
def admits_voi(cid: CID, decision: str, node: str) -> bool:
    """Return True if cid admits value of information for node.
    - A CID admits value of information for a node X if:
    i) X is not a descendant of the decision node, D.
    ii) X is d-connected to U given Fa_D \ {X}, where U ∈ U ∩ Desc(D)
    ("Agent Incentives: a Causal Perspective" by Everitt, Carey, Langlois, Ortega, and Legg, 2020)
    """
    if len(cid.agents) > 1:
        raise Exception(
            f"This CID has {len(cid.agents)} agents. This incentive is currently only \
                        valid for CIDs with one agent.")

    if node not in cid.nodes:
        raise Exception(f"{node} is not present in the cid")
    if decision not in cid.nodes:
        raise Exception(f"{decision} is not present in the cid")
    if not cid.sufficient_recall():
        raise Exception("Voi only implemented graphs with sufficient recall")
    if node in nx.descendants(cid, decision) or node == decision:
        return False

    cid2 = cid.copy_without_cpds()
    cid2.add_edge(node, decision)
    req_graph = requisite_graph(cid2)
    return node in req_graph.get_parents(decision)
Beispiel #2
0
def admits_ri(cid: CID, decision: str, node: str) -> bool:
    """
    Return True if cid admits a response incentive on node.
     - A CID G admits a response incentive on X ∈ V \ {D} if
    and only if the reduced graph G* min has a directed path X --> D.
    ("Agent Incentives: a Causal Perspective" by Everitt, Carey, Langlois, Ortega, and Legg, 2020)
    """
    if len(cid.agents) > 1:
        raise Exception(
            f"This CID has {len(cid.agents)} agents. This incentive is currently only \
                        valid for CIDs with one agent.")

    if node not in cid.nodes:
        raise Exception(f"{node} is not present in the cid")
    if decision not in cid.nodes:
        raise Exception(f"{decision} is not present in the cid")
    if not cid.sufficient_recall():
        raise Exception("Voi only implemented graphs with sufficient recall")
    if node == decision:
        return False

    req_graph = requisite_graph(cid)
    if find_all_dir_paths(req_graph, node, decision):
        return True

    return False
Beispiel #3
0
def admits_dir_voc(cid: CID, decision: str, node: str) -> bool:
    """
    Return True if a single-decision cid admits direct positive value of control for node.
    - A single-decision CID G admits positive value of control for a node X ∈ V \ {D} if and
    only if there is a directed path X --> U in the reduced graph G∗.
    - The path X --> U may or may not pass through D.
    - The agent has a direct value of control incentive on D if the path does not pass through D.
    - The agent has an indirect value of control incentive on D if the path does pass through D
    and there is also a backdoor path X--U that begins backwards from X (...<- X) and is
    active when conditioning on Fa_D \ {X}
    """
    if node not in cid.nodes:
        raise Exception(f"{node} is not present in the cid")
    if decision not in cid.nodes:
        raise Exception(f"{decision} is not present in the cid")

    agent_utilities = cid.all_utility_nodes
    req_graph = requisite_graph(cid)

    if not admits_voc(cid, decision, node):
        return False

    for util in agent_utilities:
        if node == util or util in nx.descendants(req_graph, node):
            x_u_paths = find_all_dir_paths(req_graph, node, util)
            if any([decision not in path for path in x_u_paths]):
                return True

    return False
Beispiel #4
0
 def test_requisite_graph(self) -> None:
     cid = get_trim_example_cid()
     self.assertFalse(requisite(cid, 'D2', 'D1'))
     self.assertTrue(requisite(cid, 'D2', 'Y2'))
     self.assertCountEqual(cid.get_parents('D2'), ['Y1', 'Y2', 'D1', 'Z1', 'Z2'])
     self.assertEqual(len(cid.edges), 12)
     req_graph = requisite_graph(cid)
     self.assertEqual(len(req_graph.edges), 7)
     self.assertCountEqual(req_graph.get_parents('D2'), ['Y2'])
Beispiel #5
0
def admits_ri(cid: CID, decision: str, node: str) -> bool:
    """
    Return True if a single-decision cid admits a response incentive on node.
     - A single decision CID G admits a response incentive on X ∈ V \ {D} if
    and only if the reduced graph G* min has a directed path X --> D.
    ("Agent Incentives: a Causal Perspective" by Everitt, Carey, Langlois, Ortega, and Legg, 2020)
    """
    if node not in cid.nodes:
        raise Exception(f"{node} is not present in the cid")
    if decision not in cid.nodes:
        raise Exception(f"{decision} is not present in the cid")
    if node == decision:
        return False

    req_graph = requisite_graph(cid)
    if find_all_dir_paths(req_graph, node, decision):
        return True

    return False
Beispiel #6
0
def admits_voc(cid: CID, decision: str, node: str) -> bool:
    """
    Return True if a single-decision cid admits positive value of control for node.
    - A single-decision CID G admits positive value of control for a node X ∈ V \ {D}
    if and only if there is a directed path X --> U in the reduced graph G∗.
    """
    req_graph = requisite_graph(cid)
    agent_utilities = cid.all_utility_nodes

    if node not in cid.nodes:
        raise Exception(f"{node} is not present in the cid")
    if decision not in cid.nodes:
        raise Exception(f"{decision} is not present in the cid")

    if node == decision:
        return False

    for util in agent_utilities:
        if node == util or util in nx.descendants(req_graph, node):
            return True

    return False