benbrastmckie / ModelChecker

A hyperintensional theorem prover for counterfactual conditional, modal, constitutive explanatory, relevance, and extensional operators.
https://pypi.org/project/model-checker/
5 stars 0 forks source link

DerivedOperator #44

Open benbrastmckie opened 1 week ago

benbrastmckie commented 1 week ago

To avoid the linter errors I made derived_definition in DerivedOperator return an empty list, added self as a first argument to each, removed the decorator, and changed from the commented lines to the uncommented lines below from DerivedOperator:

def __init__(self, semantics):
    super().__init__(semantics)
    op_subclass = self.__class__
    # if len(inspect.signature(op_subclass.derived_definition).parameters) == 0:
    if len(inspect.signature(self.derived_definition).parameters) == 0:
        raise NameError(
            f"Your derived operator class {op_subclass} is missing a derived_definition. "
            f"Please add it as a class property of {op_subclass}."
        )
    # derived_def_num_args = len(inspect.signature(op_subclass.derived_definition).parameters)
    derived_def_num_args = len(inspect.signature(self.derived_definition).parameters)
    op_name = op_subclass.__name__
    mismatch_arity_msg = (
        f"the specified arity of value {self.arity} for the DerivedOperator "
        f"class {op_name} does not match the number of arguments received "
        f"by {op_name}'s derived_definitino property "
        f"({derived_def_num_args}) arguments currently).")
    assert self.arity == derived_def_num_args, mismatch_arity_msg

This seems to handle all of the linter errors. I'm wondering if op_subclass can also be dropped as now it only appears in error messages, changing those instances to self. Let me know if you think this is a reasonable fix. If so, I'll clean up the comments, but if anything seems worth saving let me know.

benbrastmckie commented 1 week ago

Just doing some testing and got the following:

  File "/home/benjamin/Documents/Philosophy/Projects/ModelChecker/Code/src/new
_checker/hidden_things.py", line 355, in __init__
    semantics.premise_behavior(prem, semantics.main_world)
  File "/home/benjamin/Documents/Philosophy/Projects/ModelChecker/Code/src/new
_checker/exposed_things.py", line 134, in true_at
    return operator.true_at(*args, eval_world)
           ^^^^^^^^^^^^^^^^
AttributeError: 'BiconditionalOperator' object has no attribute 'true_at'

I ran the following:

premises = ["(D \\leftrightarrow A)", "((A \\rightarrow (B \\wedge C)) \\wedge D)"]
conclusions = ["\\neg B"]

Here is the definition I used:

# NOTE: third try
def derived_definition(self, leftarg, rightarg):
    neg_left = [NegOperator, leftarg]
    neg_right = [NegOperator, rightarg]
    both_true = [AndOperator, leftarg, rightarg]
    both_false = [AndOperator, neg_left, neg_right]
    return [OrOperator, both_true, both_false]

I also experimented with the following but got the same error:

# NOTE: four try
def derived_definition(self, leftarg, rightarg):
    right_to_left = [ConditionalOperator, leftarg, rightarg]
    left_to_right = [ConditionalOperator, rightarg, leftarg]
    return [AndOperator, right_to_left, left_to_right]

The ConditionalOperator works great and the definition is similar.

benbrastmckie commented 1 week ago

Fixed it. I had BiconditionalOperator(Operator) instead of BiconditionalOperator(DerivedOperator). Seems to all be working great! This is a really nice utility and will definitely save time later on.