4

I have a case struct which holds an expression with the type of SymbolicUtils.Term{Bool}. Also I have defined rules from SymbolicUtils library which takes these cases as input and simplifies them. In order to simplify these cases the form should be like: (i == j) & (i == 3) & (j == 3) & (i == 3) & (j == 3) without unnecessary parentheses. For example it's not good to have this one: ((i == j) & ((i == 3) & (j == 3))) & ((i == 3) & (j == 3))

In order to solve this, I thought I can convert the expression with extra parentheses to string then I can process this string to get the desired form. I did this actually:

function reduce_parentheses(case::Case)
   main_exp_string = ""
   exp_to_str = repr(case.condition) #Convert case's condition into a string.
   condition_list = split(exp_to_str, "&") #Split cases to subcases into a list.
   for i in 1:length(condition_list) # Iterate cases list one by one.
      stripped = lstrip(condition_list[i], [' ']) #Remove the whitespace at the beginning of the expression.
      stripped = rstrip(stripped, [' ']) #Remove the whitespace at the end of the expression.

      stripped = lstrip(stripped, ['(']) #Add opening parentheses at the beginning of the expression.
      stripped = rstrip(stripped, [')']) #Add closing parentheses at the end of the expression.

      #Get the desired form.
      if i != 1
         main_exp_string = main_exp_string * ' ' * '(' *stripped * ')'
      elseif i == 1
         main_exp_string = main_exp_string * '(' *stripped * ')'
      end
      if i != length(condition_list)
         main_exp_string = main_exp_string * ' ' * '&'
      end

    end
    println(main_exp_string)
    exp = (Meta.parse(main_exp_string)) #Convert string back to an expression.
    println(typeof(eval(exp))) #Convert expression back to SymbolicUtils.Term{Bool} type.
end

I can get the string in the desired form but when I try to turn it back into an expression I'm getting unnecessary parentheses with the different form because it's evaluating left to right I think.

Example:

The case with unnecessary parentheses: ((i == j) & ((i == 3) & (j == 3))) & ((i == 3) & (j == 3))

The processed string(desired form): (i == j) & (i == 3) & (j == 3) & (i == 3) & (j == 3)

Evaluated case: ((((i == j) & (i == 3)) & (j == 3)) & (i == 3)) & (j == 3)

How can I solve this? Maybe instead of converting it into a string can I do it in a smarter way?

patoglu
  • 401
  • 4
  • 16
  • 1
    Interesting question. It seems best to do this somehow via the internal representation of the expressions in question, instead of string processing. Is it possible to declare that `&` is associative? Associativity is the property which expresses the idea that parentheses don't matter when humans are doing the algebra. – Robert Dodier Jan 01 '21 at 19:30
  • Yes, that would solve the problem but I don't think it's possible to declare operators with specified properties. – patoglu Jan 02 '21 at 16:27
  • 1
    A brief web search suggests that the symbolic capabilities of Julia are provided via Sympy. If that's correct, maybe you can find more info by asking about operator properties for Sympy, since maybe people are more directly familiar with that. – Robert Dodier Jan 02 '21 at 19:11

0 Answers0