sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
12.72k stars 4.37k forks source link

Logical operators precedence in the sympy.logic module #8863

Open laituan245 opened 9 years ago

laituan245 commented 9 years ago

In sympy, probably the implication operators (>> and <<) have higher precedence than the AND , OR , and NOT operators. For example:

>>> from sympy import *
>>> false & true >> true
False

In this case, if the AND operator (&) had higher precedence than the implication operator (>>), the result would be True.

But the Wikipedia says that AND, OR, and NOT operators actually have higher precedence than the implication operators (http://en.wikipedia.org/wiki/Logical_connective#Order_of_precedence).

I guess the reason for this problem is because the code in boolalg.py overloads the operators | (bitwise OR) , ! (bitwise NOT), & (bitwise AND), >> (right shift), and << (left shift) of Python. And hence, it must conform to the precedence rules of Python. And in Python, shift operators have higher precedence than other bitwise operators. That explains why in sympy, the implication operators (>> and <<) have higher precedence than the AND , OR , and NOT operators.

I don't know if there is any easy fix for this. Because Python doesn't allow you to change the precedence rules (http://stackoverflow.com/questions/11811051/change-operator-precedence-in-python)

asmeurer commented 8 years ago

There's no way to change operator precedence in Python, unfortunately. This is a pitfall to overriding >> unfortunately, and the only way around it is to either avoid >> (use Implies), or to remember to always parenthesize things.

SymPy already assumes that AND and IMPLIES have no implied relative precedence in its pretty printer:

In [1]: And(x, Implies(y, z))
Out[1]: x ∧ (y → z)

In [2]: Implies(And(x, y), z)
Out[2]: (x ∧ y) → z

I suppose if you work with these symbols enough it might be convenient to assume precedence so that you don't need so many parentheses (and AND higher than IMPLIES probably makes the most sense). Personally, when I see x ∧ y → z I'm not quite sure what it should mean.

It's also worth pointing out that the inequality operators (<, <=, >, >=) do have lower precedence than & and | (https://docs.python.org/3/reference/expressions.html#operator-precedence). I'm not sure if it's worth using, them, though, given their usual meaning for normal expressions.

At any rate, we should document this.

zepol-solrac commented 7 years ago

Hi, i don't uinderstand what is the problem, 'cause in logical interpretation procedure it's clear about WFF (well formed formula) wich means "one formula have only one interpretation". If a formula have one or more interpretation it's ambiguos and are not part of language. I think, the program must show "error: not WFF".

asmeurer commented 7 years ago

Every formula does indeed have one interpretation (Python's grammar is not ambiguous). The problem is that that interpretation might not be what the user expects.