code: def generate_test(
      attribute_groups: Dict[str, List[str]],
      subject: str,
      subject_category: str,
      rules: List[LanguageRule],
      use_specific_attributes: bool,
      p_consequenceless=0.1,
  ) -> Tuple[LanguageFact, List[LanguageRule], LanguageFact]:
      """Generates a test case given a set of rules, i.e. a statement about the subject from which something
      can be potentially deduced given the rules. We include an argument, p_consequenceless, to re-roll with
      some probability if the generated fact does not allow anything to be determined.
      """
  
      # The generic attributes which the test fact will assign to the subject
      test_attributes: List[str] = random.sample(
          list(attribute_groups.keys()), 2
      )
      # The specific versions of the test attributes
      test_attributes_specific: List[str] = [
          random.choice(attribute_groups[subcondition])
          for subcondition in test_attributes
      ]
      test_consequents: List[
          str
      ] = []  # The attributes implied by the test attributes and rules
      test_rules_used: List[LanguageRule] = []
      for rule in rules:
          if rule.consequent in test_attributes:
              continue
          if rule.condition_conjunction == "and":
              if set(rule.condition).issubset(test_attributes):
                  test_rules_used.append(rule)
                  test_consequents.append(rule.consequent)
          elif rule.condition_conjunction == "or":
              if not set(rule.condition).isdisjoint(test_attributes):
                  test_rules_used.append(rule)
                  test_consequents.append(rule.consequent)
      if (
          len(test_consequents) == 0
          and random.random() > p_consequenceless
      ):
          return generate_test(
              attribute_groups,
              subject,
              subject_category,
              rules,
              use_specific_attributes,
              p_consequenceless,
          )
  
      test_fact: LanguageFact = LanguageFact(
          subject,
          subject_category,
          specifier_type="the",
          specific_attributes=test_attributes_specific,
          generic_attributes=test_attributes,
          use_specific_attributes=use_specific_attributes,
      )
  
      target_fact: LanguageFact = dataclasses.replace(
          test_fact,
          specific_attributes=test_consequents,
          generic_attributes=test_consequents,
      )
  
      return test_fact, test_rules_used, target_fact
  
imports: import random
  import dataclasses
  from copy import copy
  from typing import List, Dict, Literal, Tuple
  from dataclasses import dataclass
  from .scenario import Scenario, Instance, Reference, TRAIN_SPLIT, VALID_SPLIT, TEST_SPLIT, CORRECT_TAG, Input, Output
label_desc: Use image node_id 3 for calling a global function with example usage: generate_test(attribute_groups, subject, subject_category, rules, use_specific_attributes, p_consequenceless) and returns: test_fact,  test_rules_used,  target_fact, generate_test