#Predicate Logic Without Negation

import itertools


class Predicate:
    def __init__(self, name, arity):
        self.name = name
        self.arity = arity

    def __repr__(self):
        return self.name


class Term:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return self.name


class Atom:
    def __init__(self, predicate, terms):
        self.predicate = predicate
        self.terms = terms

    def __repr__(self):
        terms_str = ", ".join(str(term) for term in self.terms)
        return f"{self.predicate}({terms_str})"


def is_formula_satisfiable(formula, domain):
    for assignment in itertools.product(*domain):
        assignment_dict = {term.name: value for term, value in zip(domain, assignment)}
        if evaluate_formula(formula, assignment_dict):
            return True

    return False


def evaluate_formula(formula, assignment):
    if isinstance(formula, Atom):
        return evaluate_atom(formula, assignment)

    # Handle conjunction (∧)
    if len(formula) > 1:
        return all(evaluate_formula(subformula, assignment) for subformula in formula)

    # Handle implication (→)
    antecedent, consequent = formula[0]
    return not evaluate_formula(antecedent, assignment) or evaluate_formula(consequent, assignment)


def evaluate_atom(atom, assignment):
    predicate = atom.predicate
    terms = atom.terms

    # Define the truth value for each predicate and its corresponding terms
    # This can be modified based on the problem requirements
    if predicate.name == "P":
        return terms[0].name == terms[1].name

    if predicate.name == "Q":
        return terms[0].name != terms[1].name

    # Handle other predicates...

    raise ValueError("Unknown predicate:", predicate)


# Example usage
domain = [Term("x"), Term("y")]

# Example formula: P(x, y) ∧ Q(y, x)
formula = [
    Atom(Predicate("P", 2), [domain[0], domain[1]]),
    Atom(Predicate("Q", 2), [domain[1], domain[0]])
]

is_satisfiable = is_formula_satisfiable(formula, domain)
print("Is formula satisfiable:", is_satisfiable)

