1 | initial version |

I can answer the "why it does that" question, anyway: Sage follows Maxima's conventions on equality testing. That is, it only returns True if it's convinced the equality holds. "False" here translates as "False or unknown".

I actually couldn't find a good workaround-- I'm not sure what the right way to fake new rewrite rules is. I guess you could confirm that the lhs and rhs agree via something like this:

```
sage: eq = arcsin(x) == 2*arctan(x/(sqrt(-x*x+1)+1))
sage: bool(eq)
False
sage: # but..
sage: bool(eq.subs(x=0))
True
sage: bool(diff(eq, x))
True
```

And if you had several cases where the "agree at one point and derivatives equal" trick works, you could put it in a function, maybe with something like this:
```
def tryharder_bool(some_expr):
# hack hack hack
if some_expr:
return True
try:
v = some_expr.variables()
if len(v) == 1:
if bool(some_expr.subs({v[0]:0})) and bool(diff(some_expr, v[0])):
return True
except:
pass
return False
```

giving
sage: bool(eq) False sage: tryharder_bool(eq) True

2 | No.2 Revision |

I can answer the "why it does that" question, anyway: Sage follows Maxima's conventions on equality testing. That is, it only returns True if it's convinced the equality holds. "False" here translates as "False or unknown".

I actually couldn't find a good workaround-- I'm not sure what the right way to fake new rewrite rules is. I guess you could confirm that the lhs and rhs agree via something like this:

```
sage: eq = arcsin(x) == 2*arctan(x/(sqrt(-x*x+1)+1))
sage: bool(eq)
False
sage: # but..
sage: bool(eq.subs(x=0))
True
sage: bool(diff(eq, x))
True
```

And if you had several cases where the "agree at one point and derivatives equal" trick works, you could put it in a function, maybe with something like ~~this:
~~this:

**Warning: untested code!**

```
def tryharder_bool(some_expr):
# hack hack hack
if some_expr:
return True
try:
v = some_expr.variables()
if len(v) == 1:
if bool(some_expr.subs({v[0]:0})) and bool(diff(some_expr, v[0])):
return True
except:
pass
return False
```

giving

`sage: bool(eq) False sage: tryharder_bool(eq) True`

3 | No.3 Revision |

I can answer the "why it does that" question, anyway: Sage follows Maxima's conventions on equality testing. That is, it only returns True if it's convinced the equality holds. "False" here translates as "False or unknown".

I actually couldn't find a good workaround-- I'm not sure what the right way to fake new rewrite rules is. I guess you could confirm that the lhs and rhs agree via something like this:

```
sage: eq = arcsin(x) == 2*arctan(x/(sqrt(-x*x+1)+1))
sage: bool(eq)
False
sage: # but..
sage: bool(eq.subs(x=0))
True
sage: bool(diff(eq, x))
True
```

And if you had several cases where the "agree at one point and derivatives equal" trick works, you could put it in a function, maybe with something like this:

**Warning: untested code!code! Will probably break when given unexpected input!**

```
def tryharder_bool(some_expr):
# hack hack hack
if some_expr:
return True
try:
if type(some_expr) == Expression and some_expr.is_relational():
v = some_expr.variables()
if len(v) == 1:
if bool(some_expr.subs({v[0]:0})) and bool(diff(some_expr, v[0])):
return True
except:
pass
return False
```

giving

```
sage: bool(eq)
False
sage: tryharder_bool(eq)
True
```

4 | No.4 Revision |

```
sage: eq = arcsin(x) == 2*arctan(x/(sqrt(-x*x+1)+1))
sage: bool(eq)
False
sage: # but..
sage: bool(eq.subs(x=0))
True
sage: bool(diff(eq, x))
True
```

And if you had several cases where the "agree at one point and derivatives equal" trick works, you could put it in a function, maybe with something like this:

**Warning: untested code! Will probably break when given unexpected input!**

```
def tryharder_bool(some_expr):
# hack hack hack
if some_expr:
return True
```~~try:
~~if type(some_expr) == Expression and some_expr.is_relational():
~~ ~~v = some_expr.variables()
~~ ~~if len(v) == 1:
~~ if bool(some_expr.subs({v[0]:0})) and bool(diff(some_expr, v[0])):
~~if some_expr.subs({v[0]:0}) and diff(some_expr, v[0]):
return True
~~ except:
pass
~~ return False

giving

```
sage: bool(eq)
False
sage: tryharder_bool(eq)
True
```

5 | added more trig simplifications |

```
sage: eq = arcsin(x) == 2*arctan(x/(sqrt(-x*x+1)+1))
sage: bool(eq)
False
sage: # but..
sage: bool(eq.subs(x=0))
True
sage: bool(diff(eq, x))
True
```

And if you had several cases where the "agree at one point and derivatives equal" trick works, you could put it in a function, maybe with something like this:

**Warning: untested code! Will probably break when given unexpected input!**

```
def tryharder_bool(some_expr):
# hack hack hack
if some_expr:
return True
if type(some_expr) == Expression and some_expr.is_relational():
v = some_expr.variables()
if len(v) == 1:
if some_expr.subs({v[0]:0}) and diff(some_expr, v[0]):
return True
return False
```

giving

```
sage: bool(eq)
False
sage: tryharder_bool(eq)
True
```

UPDATE:

For some of the other cases mentioned in the comments, playing around with the trig_* functions and/or converting to exponential form works:

```
sage: eq1 = arcsin(x) == 2*arctan(x/(sqrt(-x*x+1)+1))
sage: eq2 = sin(x) == 2*sin(x/2)*cos(x/2)
sage: eq3 = sin(2*x) == 2*sin(x)*cos(x)
sage: eq4 = tan(x/2) == sin(x)/(1+cos(x))
sage: eqs = eq1, eq2, eq3, eq4
sage: [bool(q) for q in eqs]
[False, False, True, False]
sage: [bool(q.trig_reduce()) for q in eqs]
[False, True, True, False]
sage: [bool(q.trig_expand()) for q in eqs]
[False, False, True, False]
sage: [bool(q.trig_expand(half_angles=True)) for q in eqs]
[False, False, True, True]
sage:
sage:
sage: eq2.maxima_methods().exponentialize()
1/2*I*e^(-I*x) - 1/2*I*e^(I*x) == 1/2*(I*e^(-1/2*I*x) - I*e^(1/2*I*x))*(e^(-1/2*I*x) + e^(1/2*I*x))
sage: eq1.maxima_methods().exponentialize()
arcsin(x) == 2*arctan(x/(sqrt(-x^2 + 1) + 1))
sage: [bool(q.maxima_methods().exponentialize()) for q in eqs]
[False, True, True, True]
sage:
sage: def trig_xeq_check(eq):
....: return bool(eq) or bool(eq.maxima_methods().exponentialize()) or (bool(eq.subs(x=0)) and bool(diff(eq,x)))
....:
sage:
sage: [trig_xeq_check(q) for q in eqs]
[True, True, True, True]
```

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.