Opened 12 years ago

# arithmetic with equations and inequalities confusing

Reported by: Owned by: burcin burcin major sage-8.2 symbolics inequality, solver, maxima kcrisman Burcin Erocal, Ralf Stephan N/A u/rws/7660-1 37c5190e9fdc3a6195a564fd3e61f2eaa06bb892

Equations and relations should behave like this: equations:

• `(a==b) +-*/ c` same as:
• `(a==b).add_to_both_sides(c)`
• `(a==b).subtract_from_both_sides(c)`
• `(a==b).multiply_both_sides(c)`
• `(a==b).divide_both_sides(c)`
• `False` if `*/0`
• `(a==b)^c` --> `a^c == b^c`
• `f(a==b)` --> `f(a)==f(b)`

relations:

• `(a<b) +- c` same as:
• `(a<b).add_to_both_sides(c)`
• `(a<b).subtract_from_both_sides(c)`
• `(a<b) */ c` same as:
• `a*/c > b*/c` for `c` real and negative, or if `c` is assumed negative
• `a*/c < b*/c` for `c` real and positive, or if `c` is assumed positive
• `False` if `c=0` or assumed zero
• if `c` contains variables (and no assumptions exist about it) raise `ArithmeticError: missing assumption: is ...>0?`
• if `c` contains no variables `ArithmeticError: multiplication of inequality with irreal`
• `(a<b)^c` --> `(a<b)^c`
• `f(a<b)` --> `f(a<b)`

Original description:

Arithmetic with inequalities can be confusing, since Sage does nothing to keep the inequality correct. For example:

```On Thu, 10 Dec 2009 00:37:10 -0800 (PST)
"marik@mendelu.cz" <marik@mendelu.cz> wrote:

> sage: f = x + 3 < y - 2
> sage: f*(-1)
> -x - 3 < -y + 2
```

It seems MMA doesn't apply any automatic simplification in this case:

```On Thu, 10 Dec 2009 09:54:36 -0800
William Stein <wstein@gmail.com> wrote:

> Mathematica does something weird and formal:
>
> In[1]:= f := x+3 < y-2;
> In[3]:= f*(-1)
> Out[3]= -(3 + x < -2 + y)
```

Maple acts more intuitively, though the way formal products are printed leaves something to be desired, IMHO:

```On Thu, 10 Dec 2009 14:15:53 -0800
William Stein <wstein@gmail.com> wrote:

> Here is what Maple does:
>
> flat:release_notes wstein\$ maple
>     |\^/|     Maple 13 (APPLE UNIVERSAL OSX)
> ._|\|   |/|_. Copyright (c) Maplesoft, a division of Waterloo Maple
>  <____ ____>  Waterloo Maple Inc.
>       |       Type ? for help.
> > f := x < y;
>                                   f := x < y
>
> > f*(-3);
>                                   -3 y < -3 x
>
> > f*z;
>                                   *(x < y, z)
>
> > f*a;
>                                   *(x < y, a)
```

We should multiply both sides of the inequality only if the argument is a real number (as opposed to a symbol with real domain), and invert the relation when the argument is negative.

Note that GiNaC leaves everything formal, like MMA, by default:

```ginsh - GiNaC Interactive Shell (ginac V1.5.3)
__,  _______  Copyright (C) 1999-2009 Johannes Gutenberg University Mainz,
(__) *       | Germany.  This is free software with ABSOLUTELY NO WARRANTY.
._) i N a C | You are welcome to redistribute it under certain conditions.
<-------------' For details type `warranty;'.

Type ?? for a list of help topics.
> f= x < y;
x<y
> f*-1;
-(x<y)
> f*-5;
-5*(x<y)
> f*-z;
-z*(x<y)
> f*z;
z*(x<y)
```

### comment:2 Changed 11 years ago by tnv

• Description modified (diff)

### comment:3 Changed 11 years ago by tnv

• Description modified (diff)

### comment:4 Changed 11 years ago by tnv

• Description modified (diff)

### comment:5 Changed 11 years ago by tnv

```sage: -1*(x < y)
-x < -y

```

this is quite dangerous (I encountered it as a bug in a project). Hopefully someone will try to fix this soon. Could it be related to this http://trac.sagemath.org/sage_trac/ticket/11309 ?

### comment:6 Changed 10 years ago by kini

I propose the following: `a*(x<y)` should not be simplified, ever, other than simplifying `a`, `x`, or `y` individually. Are there any problems with this?

### comment:7 Changed 10 years ago by kcrisman

Given the ticket description details above and the discussion at #11309 and here, I think that Burcin's original proposal of

• keeping the same if we know `a` is positive
• reversing if we know `a` is negative (presumably in both of these cases only if `a` is coerced to the reals successfully, as Burcin says)
• (not in original but reasonable) return something like `False` for `<` and `=` for `<=` if `a=0`?
• returning something formal otherwise

seems best. It does seem reasonable to multiply by `-1`, after all, and tnv is right that this should either reverse the inequality or remain formal.

### comment:8 Changed 10 years ago by kini

It doesn't seem at all reasonable to me to distribute multiplication over a relation. When you distribute multiplication over addition, the addition expression `(a+b)` lives in the same space as `a` and `b` individually. This is not the case with `(x<y)` and `x` and `y`.

There is no mathematical rationale for saying that `(-1)*(x<y)` is `-x < -y` or `-x > -y` or anything other than just `(-1)*(x<y)`. I'm sure many can recall when they first learned basic algebra that their teacher was careful to say "we multiply both sides of the equation by c", not "we multiply the equation by c", just as he or she was careful to say "we multiply both the numerator and denominator of the fraction by c", rather than the dangerous "we multiply the fraction by c"!

If we allow multiplication to distribute over `x<y` as if it were a two-coordinate vector, do we want other similarities with vector arithmetic to come into play? Should `(a+b)*(x<y)` be equal to `a*(x<y) + b*(x<y)`? Now we have addition and presumably subtraction of relational expressions. What is `0*(x<y)`? What is `(x<y) + (z>y)`? Should we attempt to reverse inequalities to make them match up when adding them? Do we then end up with `(x+y<y+z)`, or `(y+z>x+y)`? Or, do we conclude that `(z>y)` is equal to `(-1)*(-z<-y)`, and so `(x<y) + (z>y) == (x<y) - (-z<-y) == (x+z<2y)`? Going beyond vector-like arithmetic, what happens when you add a scalar to a relational expression? What is `(x<y) + 3`?

I think the most sensible answer to all the above questions is the following: we should not perform arithmetic on relational expressions; when asked to do so, we should return a purely formal expression.

If the title of this ticket disagrees with that answer, I can make another ticket to implement it, but I'm just wondering if anyone disagrees with me strongly about this.

### comment:9 Changed 10 years ago by kcrisman

Well, we could go to the Ginac/Mathematica way too, instead of the Maple way. But now that #11309 is on the way in, probably it's time to deal with this. FWIW, Maxima seems to go that way as well.

```(%i1) x<y;
(%o1)                                x < y
(%i2) a:x<y;
(%o2)                                x < y
(%i3) a;
(%o3)                                x < y
(%i4) -1*a;
(%o4)                              - (x < y)
(%i5) b*a;
(%o5)                              b (x < y)
```

Maybe Burcin has a comment; I don't have that strong of feelings, though I'm partial to

• `(x<y)+3 == x+3<y+3`
• `0*(x<y) is False`

but those may just be sentimental, as you suggest.

### comment:10 Changed 10 years ago by kini

Honestly I thought the most likely response would be `0*(x<y) == 0`. `False` is an even stranger result because now you have `(x<y) == (1+0)*(x<y) == (x<y) + False`, so either `False` is now another additive identity (on relations, anyway), thus breaking the universality of `? - ? = 0`, or `False == 0`, which is another can of worms...

And if `(x<y)+3 == (x+3<y+3)`, then presumably `3 == (3<3) == False`...?

None of this makes any sense, IMHO. I think it would be best to go the Mathematica/GiNaC/Maxima way, as shown in your Maxima output, rather than the Maple way.

### comment:11 Changed 9 years ago by robert_dodier

For the record, Maxima has a share package which implements arithmetic on inequalities.

```(%i1) load (ineq);
(%o1) /home/robert/maxima/maxima-git/maxima-code/share/simplification/ineq.mac
(%i2) e:a < b;
(%o2)                                a < b
(%i3) x*e;
Is  x  positive, negative, or zero?
p;
(%o3)                              a x < b x
(%i4) x*e;
Is  x  positive, negative, or zero?
n;
(%o4)                              a x > b x
(%i5) x*e;
Is  x  positive, negative, or zero?
z;
(%o5)                              (a < b) x
```

I gather that's similar to what Maple does.

prototype patch

### comment:12 Changed 9 years ago by burcin

attachment:trac_7660-inequality_arithmetic.patch comments out a few lines in `_add_`, `_mul_`, etc., methods of symbolic expressions to pass the arithmetic on to GiNaC directly. I don't have time to test this and verify that it returns sensible answers, however we decide to define "sensible". Please test, see what doctests fail and try to produce horrific wrong results.

Quite a few doctests and some documentation will have to change to match this new design decision. I'd like to make sure we agree on the behavior before trying to produce a clean patch. Of course, I'd appreciate help with the documentation in any case.

### comment:13 Changed 9 years ago by jdemeyer

• Milestone changed from sage-5.11 to sage-5.12

### comment:14 Changed 8 years ago by vbraun_spam

• Milestone changed from sage-6.1 to sage-6.2

### comment:15 Changed 8 years ago by rws

OK that patch applies cleanly with `patch -l`. It results in

```sage: var('x')
x
sage: x>1
x > 1
sage: ie=_
sage: ie*-1
-(x > 1)
sage: solve(_,x)
...
RuntimeError: ECL says: THROW: The catch MACSYMA-QUIT is undefined.
```

I refrained from starting any doctests.

### comment:16 Changed 8 years ago by rws

• Branch set to u/rws/ticket/7660
• Modified changed from 02/17/14 15:06:42 to 02/17/14 15:06:42

### comment:17 Changed 8 years ago by rws

• Commit set to d2801be816c9c0ea801f760b762d3c47f1b8c45b
• Keywords inequality solver maxima added

New commits:

 ​d2801be `[mq]: trac_7660-inequality_arithmetic.patch`

### comment:18 Changed 8 years ago by rws

• Work issues set to fix bug

Here are the statements sent via `maxima_eval("#\$%s\$"%statement)`:

Before:

```sage: solve(-(x > 1),x)
sage0 : (x)*(-1) > -1
sage1 : solve_rat_ineq(sage0)
_tmp_ : sage1
kill(sage1)
kill(sage0)
[[x < 1]]
```

After:

```sage: solve(-(x > 1),x)
sage12 : (x > 1)*(-1) = 0
sage13 : x
sage14 : solve(sage12,sage13)
kill(sage13)
kill(sage14)
_tmp_ : [x>1=0]          <---------?
kill(sage12)
```

Apparently, Sage's last statement sent is the result itself (no idea why), and maxima then barfs because it can't digest its own output. In maxima:

```(%i11) solve((x > 1)*(-1) = 0,x);
(%o11)                            [x > 1 = 0]
(%i12) [x>1=0];
incorrect syntax: Found logical expression where algebraic expression expected
[x>1=
^
```

In summary there are three problems:

• 46 doctests fail in symbolic alone
• maxima can't handle the formal expressions generated via this patch, and `solve()` will fail because it uses maxima solve() and not solve_rat_ineq() (probably because the expression looks like an algebraic). However:
```sage: solve_ineq((x>1)*(-1),[x,y])
#0: solve_rat_ineq(ineq=-(x > 1))
...
TypeError: ECL says: Error executing code in Maxima: solve_rat_ineq:  -(x > 1)  is not an inequality.
```

So maxima refuses to handle the formal expression generated by this patch, and this means they cannot be solved, regardless of method called. So, in addition, `solve()` should be changed to do simplification of these expressions before handing them on. This special simplification avoids all issues raised in comment:10. It can be implemented after this ticket (#15906).

• `calculus.py:symbolic_expression_from_maxima_string()` should catch maxima `RuntimeError`s from `ecl.c` and rethrow them with meaningful information. (#15902)

`

Last edited 8 years ago by rws (previous) (diff)

### comment:19 Changed 8 years ago by git

• Commit changed from d2801be816c9c0ea801f760b762d3c47f1b8c45b to 39d85bf4e577abc0e9c6136c396e2d234243188c

Branch pushed to git repo; I updated commit sha1. New commits:

 ​39d85bf `Merge branch 'ticket/7660' into tmp`

### comment:20 Changed 8 years ago by git

• Commit changed from 39d85bf4e577abc0e9c6136c396e2d234243188c to ea75f5b519907a28b00f1d8d79469f80cc128015

Branch pushed to git repo; I updated commit sha1. New commits:

 ​ea75f5b `fix relational.add/sub/mul/div_both_sides(); fix doctests`

### comment:21 Changed 8 years ago by rws

• Authors set to Burcin Erocal, Ralf Stephan
• Status changed from new to needs_review
• Work issues fix bug deleted

### comment:22 Changed 8 years ago by git

• Commit changed from ea75f5b519907a28b00f1d8d79469f80cc128015 to de2f0a08b18ce8255a6544ce35ce52ac1f55a231

Branch pushed to git repo; I updated commit sha1. New commits:

 ​de2f0a0 `Merge branch 'develop' (6.2.beta4) into ticket/7660`

### comment:23 Changed 8 years ago by git

• Commit changed from de2f0a08b18ce8255a6544ce35ce52ac1f55a231 to 5d934153cf7bea5f985b2ce63113652af45aa2be

Branch pushed to git repo; I updated commit sha1. New commits:

 ​c75a38e `Merge branch 'develop' into rev/7660` ​5d93415 `Merge branch 'develop' into rev/7660`

### comment:24 Changed 8 years ago by vbraun_spam

• Milestone changed from sage-6.2 to sage-6.3

### comment:25 Changed 8 years ago by vbraun_spam

• Milestone changed from sage-6.3 to sage-6.4

### comment:26 follow-up: ↓ 28 Changed 8 years ago by aapitzsch

• Status changed from needs_review to needs_work

Please use python3 compatible `raise TypeError` syntax.

### comment:27 Changed 8 years ago by git

• Commit changed from 5d934153cf7bea5f985b2ce63113652af45aa2be to 30cc86077172f9e57c6b5df06b40158e17e2320d

Branch pushed to git repo; I updated commit sha1. New commits:

 ​cb6af46 `Merge branch 'develop' into t/7660/ticket/7660` ​30cc860 `7660: replace old-style exception strings`

### comment:28 in reply to: ↑ 26 Changed 8 years ago by rws

Please use python3 compatible `raise TypeError` syntax.

Done. Still, doctests fail in `expression.pyx`.

### comment:30 Changed 7 years ago by jdemeyer

I'm just now looking at this ticket and personally I don't like to lose the ability to compute with relations. I think that the fact that `(a == b)^2` returns `a^2 == b^2` is a feature, not a bug. I'd say it's up to the user to ensure that the operation makes sense.

Would it be possible to keep the old behaviour for equalities `==` at least?

### comment:31 follow-up: ↓ 32 Changed 7 years ago by rws

• Description modified (diff)
• Summary changed from arithmetic with inequalities confusing to arithmetic with equations and inequalities confusing

Let's start this fresh. To summarize, what's wanted is the following:

equations:

• `(a==b) +-*/ c` same as:
• `(a==b).add_to_both_sides(c)`
• `(a==b).subtract_from_both_sides(c)`
• `(a==b).multiply_both_sides(c)`
• `(a==b).divide_both_sides(c)`
• `False` if `*/0`
• `(a==b)^c` --> `a^c == b^c`
• `f(a==b)` --> `f(a==b)`

relations:

• `(a<b) +- c` same as:
• `(a<b).add_to_both_sides(c)`
• `(a<b).subtract_from_both_sides(c)`
• `(a<b) */ c` same as:
• `a*/c > b*/c` for `c` real and negative, or if `c` is assumed negative
• `a*/c < b*/c` for `c` real and positive, or if `c` is assumed positive
• `False` if `c=0`
• `(a<b)^c` --> `(a<b)^c`
• `f(a<b)` --> `f(a<b)`

Question: Real or: if coerced to the reals successfully? A followup extension would be like Maxima's ineq package, i.e., ask before doing a sign switch.

### comment:32 in reply to: ↑ 31 ; follow-up: ↓ 33 Changed 7 years ago by jdemeyer

• `f(a==b)` --> `f(a==b)`

What does `f(a==b)` even mean? I would go for `f(a) == f(b)`.

relations:

• `(a<b) */ c` same as:
• `a*/c > b*/c` for `c` real and negative, or if `c` is assumed negative
• `a*/c < b*/c` for `c` real and positive, or if `c` is assumed positive
• `False` if `c=0`

What if neither of the above conditions is true? `raise ArithmeticError` in that case?

### comment:33 in reply to: ↑ 32 ; follow-up: ↓ 34 Changed 7 years ago by rws

• `(a<b) */ c`

What if neither of the above conditions is true? `raise ArithmeticError` in that case?

Not if `c` contains variables. Is there even a way of determining this?

### comment:34 in reply to: ↑ 33 ; follow-up: ↓ 35 Changed 7 years ago by jdemeyer

Not if `c` contains variables.

What would you propose that `x * (y < z)` answers then?

Version 0, edited 7 years ago by jdemeyer (next)

### comment:35 in reply to: ↑ 34 Changed 7 years ago by rws

What would you propose that `x * (y < z)` answers then (where `x`, `y` and `z` are variables)?

Since this ticket will check for assumptions, if there is none we should raise an `ArithmeticError` demanding one.

### comment:36 Changed 7 years ago by jdemeyer

So my statement to `raise ArithmeticError` if neither condition is true still remains.

### comment:37 Changed 7 years ago by rws

• Description modified (diff)

### comment:38 Changed 7 years ago by rws

• Description modified (diff)

### comment:39 in reply to: ↑ description Changed 7 years ago by jdemeyer

• if `c` contains variables (and no assumptions exist about it) raise `ArithmeticError: missing assumption: is ...>0?`
• if `c` contains no variables `ArithmeticError: multiplication of inequality with irreal`

I think it will be easier if these are just one case.

### comment:40 Changed 7 years ago by rws

• Branch changed from u/rws/ticket/7660 to public/7660

### comment:41 Changed 7 years ago by rws

• Commit changed from 30cc86077172f9e57c6b5df06b40158e17e2320d to 14ede75c5f56554ef9e61c094d3bb4e971280314
• Status changed from needs_work to needs_review

Since the `f()` stuff requires changes in function base classes, and assumptions are also an involvement, I'll leave both to followup tickets. Please review.

New commits:

 ​855fba8 `7660: power of inequality no longer distributes over sides` ​47251f2 `7660: switch inequality sign with negative reals, False if zero; provide original behaviour in mul/div_both_sides()` ​efeab1c `7660: same with division` ​14ede75 `7660: add errors; fix some doctests`

### comment:42 follow-up: ↓ 43 Changed 7 years ago by jdemeyer

Why convert to `RR`? I would simply use

```if right == 0:
...
elif right >= 0:
...
elif right <= 0:
...
else:
raise ArithmeticError(...)
```

This handles non-constant symbolic expressions also.

### comment:43 in reply to: ↑ 42 Changed 7 years ago by rws

Why convert to `RR`? I would simply use

```if right == 0:
...
elif right >= 0:
...
elif right <= 0:
...
else:
raise ArithmeticError(...)
```

This handles non-constant symbolic expressions also.

Seems we have to open a ticket?

```sage: def f(ex):
if ex==0:
print 'zero'
elif ex<0:
print 'minus'
else:
print 'else'
....:
sage: ex=-I
sage: f(ex)
minus
sage: bool(-I<0)
True
sage: bool(I>0)
True
```

### comment:44 Changed 7 years ago by git

• Commit changed from 14ede75c5f56554ef9e61c094d3bb4e971280314 to d89485d979ab0e51bd1b8b2e1ea463878b4d6ad5

Branch pushed to git repo; I updated commit sha1. New commits:

 ​37f8ba4 `Merge branch 'develop' into t/7660/public/7660` ​d89485d `7660: last fixes`

### comment:45 Changed 7 years ago by git

Branch pushed to git repo; I updated commit sha1. New commits:

 ​17c4e8a `Merge branch 'develop' into t/7660/public/7660`

### comment:46 Changed 7 years ago by chapoton

• Description modified (diff)

### comment:47 Changed 7 years ago by chapoton

• Milestone changed from sage-6.4 to sage-6.7

### comment:48 Changed 7 years ago by git

• Commit changed from 17c4e8ad25114508ca1f722f66b497b594bca595 to 463a676f26b010d4aa9079ecdccc88f20490f8d3

Branch pushed to git repo; I updated commit sha1. New commits:

 ​463a676 `Merge branch 'develop' into t/7660/public/7660`

### comment:49 Changed 7 years ago by chapoton

• Milestone changed from sage-6.7 to sage-6.8

### comment:50 Changed 7 years ago by git

• Commit changed from 463a676f26b010d4aa9079ecdccc88f20490f8d3 to 32f923d9489e7538f9bf36e2a297cce348b7bbb2

Branch pushed to git repo; I updated commit sha1. New commits:

 ​32f923d `Merge branch 'develop' into t/7660/public/7660`

### comment:51 Changed 7 years ago by git

• Commit changed from 32f923d9489e7538f9bf36e2a297cce348b7bbb2 to 7be89303312e8a879cfed49f25091e5848adda43

Branch pushed to git repo; I updated commit sha1. New commits:

 ​7be8930 `Merge branch 'develop' into t/7660/public/7660`

### comment:52 Changed 6 years ago by aapitzsch

• Status changed from needs_review to needs_work
• Work issues set to rebase

### comment:53 follow-up: ↓ 54 Changed 6 years ago by rws

@aapitzsch Are you willing to review this issue?

### comment:54 in reply to: ↑ 53 Changed 6 years ago by aapitzsch

@aapitzsch Are you willing to review this issue?

No. Sorry for the noise.

### comment:55 Changed 6 years ago by git

• Commit changed from 7be89303312e8a879cfed49f25091e5848adda43 to 60ac7182b892db0f5e670bb089e8b72e12c1ba1e

Branch pushed to git repo; I updated commit sha1. New commits:

 ​60ac718 `Merge branch 'develop' into t/7660/public/7660`

### comment:56 Changed 6 years ago by rws

• Milestone changed from sage-6.8 to sage-7.4
• Status changed from needs_work to needs_review
• Work issues rebase deleted

### comment:57 Changed 6 years ago by git

• Commit changed from 60ac7182b892db0f5e670bb089e8b72e12c1ba1e to aebaf17f072f7c06e55d2025a4279c5c78ec7a48

Branch pushed to git repo; I updated commit sha1. New commits:

 ​aebaf17 `missing change due to incomplete merge conflict`

### comment:58 Changed 5 years ago by rws

• Status changed from needs_review to needs_work

Relevant doctest fail in `src/sage/misc/sageinspect.py`

### comment:59 Changed 5 years ago by git

• Commit changed from aebaf17f072f7c06e55d2025a4279c5c78ec7a48 to 2edba4d8277d04329315a95c7c07ebc5dc69529a

Branch pushed to git repo; I updated commit sha1. New commits:

 ​b769b4b `Merge branch 'develop' into t/7660/public/7660` ​2edba4d `7660: fix last line test again`

### comment:60 Changed 5 years ago by rws

• Milestone changed from sage-7.4 to sage-7.6
• Status changed from needs_work to needs_review

### comment:61 Changed 5 years ago by chapoton

• Status changed from needs_review to needs_work

does not apply

### comment:62 Changed 5 years ago by git

• Commit changed from 2edba4d8277d04329315a95c7c07ebc5dc69529a to 352c685e2446d6fcbbb908d0282109fcab1795c3

Branch pushed to git repo; I updated commit sha1. New commits:

 ​352c685 `Merge branch 'develop' into t/7660/public/7660`

### comment:63 Changed 5 years ago by rws

• Status changed from needs_work to needs_review

### comment:64 Changed 5 years ago by chapoton

• Status changed from needs_review to needs_work

does not apply

### comment:65 Changed 5 years ago by rws

In the course of this ticket already 12 merge commits were added. The branch has 8 so I'm doing a squash.

### comment:66 Changed 5 years ago by rws

• Branch changed from public/7660 to u/rws/7660-1

### comment:67 Changed 5 years ago by rws

• Commit changed from 352c685e2446d6fcbbb908d0282109fcab1795c3 to bb1aae09cd6e1ff08126d928af3cb1f4fdfb36f6
• Milestone changed from sage-7.6 to sage-8.1
• Status changed from needs_work to needs_review

New commits:

 ​bb1aae0 `7660: fix arithmetic with equations and inequalities`

### comment:68 Changed 5 years ago by chapoton

• Milestone changed from sage-8.1 to sage-8.2
• Status changed from needs_review to needs_work

does not apply

### comment:69 Changed 5 years ago by git

• Commit changed from bb1aae09cd6e1ff08126d928af3cb1f4fdfb36f6 to 37c5190e9fdc3a6195a564fd3e61f2eaa06bb892

Branch pushed to git repo; I updated commit sha1. New commits:

 ​37c5190 `Merge branch 'develop' into t/7660/7660-1`
Note: See TracTickets for help on using tickets.