From d35c7b22e6b1f2d110e16a6a61b9347dacc4dede Mon Sep 17 00:00:00 2001
From: Chris Sangwin <C.J.Sangwin@ed.ac.uk>
Date: Wed, 17 Jul 2024 15:02:10 +0100
Subject: [PATCH] Fix to issue #1220: display of x-0, x-0.0 etc.  That us unary
 minus and 0.

---
 stack/maxima/stackmaxima.mac   |  2 +-
 tests/castext_test.php         | 19 +++++++++++++++++++
 tests/input_algebraic_test.php | 24 ++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/stack/maxima/stackmaxima.mac b/stack/maxima/stackmaxima.mac
index 6135dbc71..286d1269d 100644
--- a/stack/maxima/stackmaxima.mac
+++ b/stack/maxima/stackmaxima.mac
@@ -898,12 +898,12 @@ texput(matrix, stack_matrix_disp)$
 unary_minus_traverse(ex) := block(
   /* We want atom here, not mapatom to catch a[4]. */
   if atom(ex) then return(ex),
+  if op(ex) = "-" and (is(first(args(ex))=0) or is(first(args(ex))=0.0)) then return(ex),
   if op(ex) = "-" and numberp(first(args(ex))) then return(ev(ex,simp)),
   if arrayp(ex) then return(arraymake(op(ex), maplist(unary_minus_traverse, args(ex)))),
   apply(op(ex), map(unary_minus_traverse, args(ex)) )
 )$
 
-
 /* Pulls out "-" to the front of any expression in a sum of products which needs it. */
 /* For example,   -(2*y^2) is ok                                                     */
 /* But            (-3)*7 is not.                                                     */
diff --git a/tests/castext_test.php b/tests/castext_test.php
index 421384cfe..b2861c8a1 100644
--- a/tests/castext_test.php
+++ b/tests/castext_test.php
@@ -2332,4 +2332,23 @@ class castext_test extends qtype_stack_testcase {
         $this->assertEquals('Underscore characters are not permitted in this input.',
             $at2->get_rendered());
     }
+
+    /**
+     * @covers \qtype_stack\stack_cas_castext2_latex
+     * @covers \qtype_stack\stack_cas_keyval
+     */
+    public function test_unary_minus_zeros() {
+        $options = new stack_options();
+        $options->set_option('simplify', false);
+        $cs2 = new stack_cas_session2([], $options, 123456);
+
+        $textinput = "{@x-0@}, {@x-0.0@}, {@x*(-0.0)@}, {@-27@}.";
+        $at1 = castext2_evaluatable::make_from_source($textinput, 'test-case');
+        $this->assertTrue($at1->get_valid());
+        $cs2->add_statement($at1);
+        $cs2->instantiate();
+
+        $this->assertEquals('\({x-0}\), \({x-0.0}\), \({x\cdot \left(-0.0\right)}\), \({-27}\).',
+            $at1->get_rendered());
+    }
 }
diff --git a/tests/input_algebraic_test.php b/tests/input_algebraic_test.php
index 36ff5bcd8..2a1bb3280 100644
--- a/tests/input_algebraic_test.php
+++ b/tests/input_algebraic_test.php
@@ -344,6 +344,30 @@ class input_algebraic_test extends qtype_stack_testcase {
         $this->assertEquals('Lowest_Terms', $state->note);
     }
 
+    public function test_validate_student_response_with_minus_zero() {
+        $options = new stack_options();
+        $el = stack_input_factory::make('algebraic', 'sans1', '1/2');
+        $el->set_parameter('forbidFloats', false);
+
+        $state = $el->validate_student_response(['sans1' => "x-0"], $options, '3.14', new stack_cas_security());
+        $this->assertEquals(stack_input::VALID, $state->status);
+        $this->assertEquals('x-0', $state->contentsmodified);
+        $this->assertEquals('\[ x-0 \]', $state->contentsdisplayed);
+        $this->assertEquals('', $state->errors);
+
+        $state = $el->validate_student_response(['sans1' => "x-0.0"], $options, '3.14', new stack_cas_security());
+        $this->assertEquals(stack_input::VALID, $state->status);
+        $this->assertEquals('x-0.0', $state->contentsmodified);
+        $this->assertEquals('\[ x-0.0 \]', $state->contentsdisplayed);
+        $this->assertEquals('', $state->errors);
+
+        $state = $el->validate_student_response(['sans1' => "x*(-0.0)"], $options, '3.14', new stack_cas_security());
+        $this->assertEquals(stack_input::VALID, $state->status);
+        $this->assertEquals('x*(-0.0)', $state->contentsmodified);
+        $this->assertEquals('\[ x\cdot \left(-0.0\right) \]', $state->contentsdisplayed);
+        $this->assertEquals('', $state->errors);
+    }
+
     public function test_validate_student_response_with_rationalized() {
         $options = new stack_options();
         $el = stack_input_factory::make('algebraic', 'sans1', '1/2');
-- 
GitLab