/// The example graphs of the identifier tests.
///
/// The graphs, the observed variables and the expected adjustment
/// sets come from `tests/causal_identifiers/example_graphs.py` of DoWhy
/// 0.14.  The file is generated by
/// `_verify/gen_identifier_testdata.py`; do not edit it by hand.

///|
/// One example graph with the adjustment sets it has to produce.
pub struct IdentifierTestCase {
  nodes : Array[String]
  edges : Array[String]
  action_nodes : Array[String]
  outcome_nodes : Array[String]
  observed_nodes : Array[String]
  biased_sets : Array[Array[String]]
  minimal_sets : Array[Array[String]]
  maximal_sets : Array[Array[String]]
  direct_maximal_sets : Array[Array[String]]
}

///|
/// A new test case.
pub fn IdentifierTestCase::new(
  nodes : Array[String],
  edges : Array[String],
  action_nodes : Array[String],
  outcome_nodes : Array[String],
  observed_nodes : Array[String],
  biased_sets : Array[Array[String]],
  minimal_sets : Array[Array[String]],
  maximal_sets : Array[Array[String]],
  direct_maximal_sets : Array[Array[String]],
) -> IdentifierTestCase {
  {
    nodes,
    edges,
    action_nodes,
    outcome_nodes,
    observed_nodes,
    biased_sets,
    minimal_sets,
    maximal_sets,
    direct_maximal_sets,
  }
}

///|
/// A frontdoor example graph with the valid and the invalid sets.
pub struct FrontdoorTestCase {
  nodes : Array[String]
  edges : Array[String]
  action_nodes : Array[String]
  outcome_nodes : Array[String]
  observed_nodes : Array[String]
  valid_sets : Array[Array[String]]
  invalid_sets : Array[Array[String]]
}

///|
/// A new frontdoor test case.
pub fn FrontdoorTestCase::new(
  nodes : Array[String],
  edges : Array[String],
  action_nodes : Array[String],
  outcome_nodes : Array[String],
  observed_nodes : Array[String],
  valid_sets : Array[Array[String]],
  invalid_sets : Array[Array[String]],
) -> FrontdoorTestCase {
  {
    nodes,
    edges,
    action_nodes,
    outcome_nodes,
    observed_nodes,
    valid_sets,
    invalid_sets,
  }
}

///|
/// A complete adjustment example graph.
pub struct CompleteTestCase {
  nodes : Array[String]
  edges : Array[String]
  action_nodes : Array[String]
  outcome_nodes : Array[String]
  observed_nodes : Array[String]
  minimal_sets : Array[Array[String]]
}

///|
/// A new complete adjustment test case.
pub fn CompleteTestCase::new(
  nodes : Array[String],
  edges : Array[String],
  action_nodes : Array[String],
  outcome_nodes : Array[String],
  observed_nodes : Array[String],
  minimal_sets : Array[Array[String]],
) -> CompleteTestCase {
  { nodes, edges, action_nodes, outcome_nodes, observed_nodes, minimal_sets, }
}

// ---- the backdoor graphs -------------------------------------------

///|
/// The pearl_backdoor_example_graph graph of the upstream test suite.
fn backdoor_case_pearl_backdoor_example_graph() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["Z1", "Z2", "Z3", "Z4", "Z5", "Z6", "X", "Y"],
    [
      "Z1->Z3", "Z1->Z4", "Z2->Z4", "Z2->Z5", "Z3->X", "Z4->X", "Z4->Y", "Z5->Y",
      "Z6->Y", "X->Z6",
    ],
    ["X"],
    ["Y"],
    ["Z1", "Z2", "Z3", "Z4", "Z5", "Z6", "X", "Y"],
    [
      ["Z4"],
      ["Z6"],
      ["Z5"],
      ["Z2"],
      ["Z1"],
      ["Z3"],
      ["Z1", "Z3"],
      ["Z2", "Z5"],
      ["Z1", "Z2"],
    ],
    [["Z1", "Z4"], ["Z2", "Z4"], ["Z3", "Z4"], ["Z4", "Z5"]],
    [["Z1", "Z2", "Z3", "Z4", "Z5"]],
    [["Z1", "Z2", "Z3", "Z4", "Z5", "Z6"]],
  )
}

///|
/// The simple_selection_bias_graph graph of the upstream test suite.
fn backdoor_case_simple_selection_bias_graph() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["Z1", "X", "Y"],
    ["X->Y", "X->Z1", "Y->Z1"],
    ["X"],
    ["Y"],
    ["Z1", "X", "Y"],
    [["Z1"]],
    [[]],
    [[]],
    [[]],
  )
}

///|
/// The simple_no_confounder_graph graph of the upstream test suite.
fn backdoor_case_simple_no_confounder_graph() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["Z1", "X", "Y"],
    ["X->Y", "Z1->X"],
    ["X"],
    ["Y"],
    ["Z1", "X", "Y"],
    [],
    [[]],
    [["Z1"]],
    [["Z1"]],
  )
}

///|
/// The pearl_simpsons_paradox_1c graph of the upstream test suite.
fn backdoor_case_pearl_simpsons_paradox_1c() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["Z", "X", "Y", "L1", "L2"],
    ["X->Y", "L1->X", "L1->Z", "L2->Z", "L2->Y"],
    ["X"],
    ["Y"],
    ["Z", "X", "Y"],
    [["Z"]],
    [[]],
    [[]],
    [[]],
  )
}

///|
/// The pearl_simpsons_paradox_1d graph of the upstream test suite.
fn backdoor_case_pearl_simpsons_paradox_1d() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["Z", "X", "Y", "L1"],
    ["X->Y", "L1->X", "L1->Z", "Z->Y"],
    ["X"],
    ["Y"],
    ["Z", "X", "Y"],
    [],
    [["Z"]],
    [["Z"]],
    [["Z"]],
  )
}

///|
/// The pearl_simpsons_paradox_2a graph of the upstream test suite.
fn backdoor_case_pearl_simpsons_paradox_2a() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["Z", "X", "Y", "L"],
    ["X->Y", "X->Z", "L->Z", "L->Y"],
    ["X"],
    ["Y"],
    ["Z", "X", "Y"],
    [["Z"]],
    [[]],
    [[]],
    [[]],
  )
}

///|
/// The pearl_simpsons_paradox_2b graph of the upstream test suite.
fn backdoor_case_pearl_simpsons_paradox_2b() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["Z", "X", "Y", "L"],
    ["X->Y", "Z->X", "L->X", "L->Y"],
    ["X"],
    ["Y"],
    ["Z", "X", "Y"],
    [],
    [],
    [],
    [],
  )
}

///|
/// The pearl_simpsons_paradox_2b_L_observed graph of the upstream test suite.
fn backdoor_case_pearl_simpsons_paradox_2b_L_observed() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["Z", "X", "Y", "L"],
    ["X->Y", "Z->X", "L->X", "L->Y"],
    ["X"],
    ["Y"],
    ["Z", "X", "Y", "L"],
    [],
    [["L"]],
    [["L", "Z"]],
    [["L", "Z"]],
  )
}

///|
/// The pearl_simpsons_machine_lvl1 graph of the upstream test suite.
fn backdoor_case_pearl_simpsons_machine_lvl1() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["Z1", "Z2", "Z3", "L", "X", "Y"],
    ["X->Y", "Z1->L", "L->Z2", "Z3->Z2", "L->X", "Z3->Y"],
    ["X"],
    ["Y"],
    ["Z1", "Z2", "Z3", "X", "Y"],
    [["Z2"], ["Z1", "Z2"]],
    [[]],
    [["Z1", "Z2", "Z3"]],
    [["Z1", "Z2", "Z3"]],
  )
}

///|
/// The book_of_why_game2 graph of the upstream test suite.
fn backdoor_case_book_of_why_game2() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["A", "B", "C", "D", "E", "X", "Y"],
    ["A->X", "A->B", "B->C", "D->B", "D->E", "X->E", "E->Y"],
    ["X"],
    ["Y"],
    ["A", "B", "C", "D", "E", "X", "Y"],
    [["B"], ["C"], ["B", "C"]],
    [[]],
    [["A", "B", "C", "D"]],
    [["A", "B", "C", "D", "E"]],
  )
}

///|
/// The book_of_why_game5 graph of the upstream test suite.
fn backdoor_case_book_of_why_game5() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["A", "B", "C", "X", "Y"],
    ["A->X", "A->B", "B->X", "C->B", "C->Y", "X->Y"],
    ["X"],
    ["Y"],
    ["A", "B", "C", "X", "Y"],
    [["B"]],
    [["C"]],
    [["A", "B", "C"]],
    [["A", "B", "C"]],
  )
}

///|
/// The book_of_why_game5_C_is_unobserved graph of the upstream test suite.
fn backdoor_case_book_of_why_game5_C_is_unobserved() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["A", "B", "C", "X", "Y"],
    ["A->X", "A->B", "B->X", "C->B", "C->Y", "X->Y"],
    ["X"],
    ["Y"],
    ["A", "B", "X", "Y"],
    [["B"]],
    [["A", "B"]],
    [["A", "B"]],
    [["A", "B"]],
  )
}

///|
/// The no_treatment_but_valid_maximal_set graph of the upstream test suite.
fn backdoor_case_no_treatment_but_valid_maximal_set() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["X", "Y", "Z1", "Z2"],
    ["X->Y", "X->Z1", "Z1->Y", "Z2->Z1"],
    ["X"],
    ["Y"],
    ["Z1", "Z2", "X", "Y"],
    [],
    [[]],
    [["Z2"]],
    [["Z1", "Z2"]],
  )
}

///|
/// The common_cause_of_mediator1 graph of the upstream test suite.
fn backdoor_case_common_cause_of_mediator1() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["X", "Y", "U", "Z", "M"],
    ["X->M", "M->Y", "U->X", "U->Z", "Z->M"],
    ["X"],
    ["Y"],
    ["X", "Y", "Z", "M"],
    [],
    [["Z"]],
    [["Z"]],
    [["M", "Z"]],
  )
}

///|
/// The common_cause_of_mediator2 graph of the upstream test suite.
fn backdoor_case_common_cause_of_mediator2() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["X", "Y", "U", "Z", "M"],
    ["X->M", "M->Y", "U->Z", "U->M", "Z->X"],
    ["X"],
    ["Y"],
    ["X", "Y", "Z", "M"],
    [],
    [["Z"]],
    [["Z"]],
    [["M", "Z"]],
  )
}

///|
/// The mbias_with_unobserved graph of the upstream test suite.
fn backdoor_case_mbias_with_unobserved() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["X", "Y", "U1", "U2", "Z", "M"],
    ["X->Y", "U1->X", "U1->M", "U2->M", "U2->Y", "Z->X"],
    ["X"],
    ["Y"],
    ["X", "Y", "Z", "M"],
    [["M", "Z"], ["M"]],
    [[]],
    [["Z"]],
    [["Z"]],
  )
}

///|
/// The iv graph of the upstream test suite.
fn backdoor_case_iv() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["X", "Y", "U", "Z"],
    ["X->Y", "U->X", "U->Y", "Z->X"],
    ["X"],
    ["Y"],
    ["X", "Y", "Z"],
    [["Z"]],
    [],
    [],
    [],
  )
}

///|
/// The mediator graph of the upstream test suite.
fn backdoor_case_mediator() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["X", "Y", "M", "W"],
    ["X->Y", "W->X", "W->Y", "X->M", "M->Y"],
    ["X"],
    ["Y"],
    ["X", "Y", "M", "W"],
    [["M"]],
    [["W"]],
    [["W"]],
    [["M", "W"]],
  )
}

///|
/// The mediator-with-conf graph of the upstream test suite.
fn backdoor_case_mediator_with_conf() -> IdentifierTestCase {
  IdentifierTestCase::new(
    ["X", "Y", "M", "W1", "W2"],
    ["X->Y", "W1->X", "W1->Y", "W2->M", "W2->Y", "X->M", "M->Y"],
    ["X"],
    ["Y"],
    ["X", "Y", "M", "W1", "W2"],
    [["M"], ["M", "W1"]],
    [["W1"]],
    [["W1", "W2"]],
    [["M", "W1", "W2"]],
  )
}

// ---- the frontdoor graphs ------------------------------------------

///|
/// The valid_singleton frontdoor graph of the upstream test suite.
fn frontdoor_case_valid_singleton() -> FrontdoorTestCase {
  FrontdoorTestCase::new(
    ["X", "Y", "Z", "M1"],
    ["X->M1", "Z->X", "Z->Y", "M1->Y"],
    ["X"],
    ["Y"],
    ["X", "Y", "M1"],
    [["M1"]],
    [["Z"]],
  )
}

///|
/// The valid_doubleton frontdoor graph of the upstream test suite.
fn frontdoor_case_valid_doubleton() -> FrontdoorTestCase {
  FrontdoorTestCase::new(
    ["X", "Y", "Z", "M1", "M2"],
    ["X->M1", "X->M2", "Z->X", "Z->Y", "M1->Y", "M2->Y"],
    ["X"],
    ["Y"],
    ["X", "Y", "M1", "M2"],
    [["M1", "M2"]],
    [["Z"], ["M1"], ["M2"]],
  )
}

///|
/// The no_frontdoor frontdoor graph of the upstream test suite.
fn frontdoor_case_no_frontdoor() -> FrontdoorTestCase {
  FrontdoorTestCase::new(
    ["E", "X", "R", "M", "Y"],
    ["E->X", "E->R", "X->M", "R->M", "M->Y"],
    ["X"],
    ["Y"],
    ["X", "R", "M", "Y"],
    [],
    [["M"], ["E", "M"], ["M", "R"]],
  )
}

///|
/// The no_frontdoor_simple frontdoor graph of the upstream test suite.
fn frontdoor_case_no_frontdoor_simple() -> FrontdoorTestCase {
  FrontdoorTestCase::new(
    ["X", "Y", "D", "B"],
    ["X->B", "D->B", "B->Y", "D->Y"],
    ["X"],
    ["Y"],
    ["X", "B", "Y"],
    [],
    [["B"], ["D"]],
  )
}

///|
/// The no_frontdoor_in_obs frontdoor graph of the upstream test suite.
fn frontdoor_case_no_frontdoor_in_obs() -> FrontdoorTestCase {
  FrontdoorTestCase::new(
    ["X", "Y", "Z", "M1", "M2"],
    ["X->M1", "X->M2", "Z->X", "Z->Y", "M1->Y", "M2->Y"],
    ["X"],
    ["Y"],
    ["X", "Y", "M1", "Z"],
    [],
    [["Z"], ["M1"], ["M2"], ["M1", "M2"]],
  )
}

///|
/// The perkovic_example_9_multiple_action_nodes_no_frontdoor frontdoor graph of the upstream test suite.
fn frontdoor_case_perkovic_example_9_multiple_action_nodes_no_frontdoor() -> FrontdoorTestCase {
  FrontdoorTestCase::new(
    ["V1", "V2", "V3", "X1", "X2", "Y"],
    ["X1->Y", "V1->X1", "V2->X1", "V3->V2", "V3->Y", "X2->V1", "X2->Y"],
    ["X1", "X2"],
    ["Y"],
    ["V1", "V2", "V3", "X1", "X2", "Y"],
    [],
    [["V1"], ["V2"], ["V3"]],
  )
}

// ---- the complete adjustment graphs -------------------------------

///|
/// The shpitser_simple_non_backdoor_adjustment_set graph of the complete adjustment tests.
fn complete_case_shpitser_simple_non_backdoor_adjustment_set() -> CompleteTestCase {
  CompleteTestCase::new(
    ["Z", "X", "Y"],
    ["X->Z", "X->Y"],
    ["X"],
    ["Y"],
    ["Z", "X", "Y"],
    [[]],
  )
}

///|
/// The van_der_zander_minimal_non_backdoor_adjustment_set graph of the complete adjustment tests.
fn complete_case_van_der_zander_minimal_non_backdoor_adjustment_set() -> CompleteTestCase {
  CompleteTestCase::new(
    ["Z1", "Z2", "X1", "X2", "Y1", "Y2"],
    ["X1->Y1", "X1->Z1", "Z1->Z2", "Z2->X2", "Y2->Z2"],
    ["X1", "X2"],
    ["Y1", "Y2"],
    ["Z1", "Z2", "X1", "X2", "Y1", "Y2"],
    [["Z1", "Z2"]],
  )
}

///|
/// The perkovic_example_8 graph of the complete adjustment tests.
fn complete_case_perkovic_example_8() -> CompleteTestCase {
  CompleteTestCase::new(
    ["X1", "X2", "Y", "V1", "V2", "V3", "V4", "V5", "L"],
    [
      "V5->X1", "V4->X1", "X1->V1", "V1->V2", "V2->X2", "X2->Y", "X1->V3", "V3->Y",
      "L->V3", "L->V2",
    ],
    ["X1", "X2"],
    ["Y"],
    ["V1", "V2", "V3", "V4", "V5", "X1", "X2", "Y"],
    [["V1", "V2"]],
  )
}

///|
/// The perkovic_example_9 graph of the complete adjustment tests.
fn complete_case_perkovic_example_9() -> CompleteTestCase {
  CompleteTestCase::new(
    ["V1", "V2", "V3", "X1", "X2", "Y"],
    ["X1->Y", "V1->X1", "V2->X1", "V3->V2", "V3->Y", "X2->V1", "X2->Y"],
    ["X1", "X2"],
    ["Y"],
    ["V1", "V2", "V3", "X1", "X2", "Y"],
    [["V2"], ["V3"]],
  )
}

///|
/// Every backdoor example graph of the upstream test suite.
pub fn backdoor_cases() -> Array[IdentifierTestCase] {
  [
    backdoor_case_pearl_backdoor_example_graph(),
    backdoor_case_simple_selection_bias_graph(),
    backdoor_case_simple_no_confounder_graph(),
    backdoor_case_pearl_simpsons_paradox_1c(),
    backdoor_case_pearl_simpsons_paradox_1d(),
    backdoor_case_pearl_simpsons_paradox_2a(),
    backdoor_case_pearl_simpsons_paradox_2b(),
    backdoor_case_pearl_simpsons_paradox_2b_L_observed(),
    backdoor_case_pearl_simpsons_machine_lvl1(),
    backdoor_case_book_of_why_game2(),
    backdoor_case_book_of_why_game5(),
    backdoor_case_book_of_why_game5_C_is_unobserved(),
    backdoor_case_no_treatment_but_valid_maximal_set(),
    backdoor_case_common_cause_of_mediator1(),
    backdoor_case_common_cause_of_mediator2(),
    backdoor_case_mbias_with_unobserved(),
    backdoor_case_iv(),
    backdoor_case_mediator(),
    backdoor_case_mediator_with_conf(),
  ]
}

///|
/// Every frontdoor example graph of the upstream test suite.
pub fn frontdoor_cases() -> Array[FrontdoorTestCase] {
  [
    frontdoor_case_valid_singleton(),
    frontdoor_case_valid_doubleton(),
    frontdoor_case_no_frontdoor(),
    frontdoor_case_no_frontdoor_simple(),
    frontdoor_case_no_frontdoor_in_obs(),
    frontdoor_case_perkovic_example_9_multiple_action_nodes_no_frontdoor(),
  ]
}

///|
/// Every complete adjustment example graph of the upstream test suite.
pub fn complete_cases() -> Array[CompleteTestCase] {
  [
    complete_case_shpitser_simple_non_backdoor_adjustment_set(),
    complete_case_van_der_zander_minimal_non_backdoor_adjustment_set(),
    complete_case_perkovic_example_8(),
    complete_case_perkovic_example_9(),
  ]
}