code: def test_uncouple_4_coupled_states():
      # j1=1/2, j2=1/2, j3=1/2, j4=1/2
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S(1) / 2, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S(1) / 2, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S(1) / 2, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S(1) / 2, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S(1) / 2, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S(1) / 2, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S(1) / 2, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S(1) / 2, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S(1) / 2, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S(1) / 2, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S(1) / 2, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S(1) / 2, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      # j1=1/2, j2=1/2, j3=1, j4=1/2
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, 1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 1),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, 1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 1),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, 0),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 0),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, 0),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 0),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, -1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, -1),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, -1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, -1),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 1),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 1),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 0),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 0),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 0),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 0),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, -1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, -1),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, -1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, -1),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, 1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 1),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, 1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 1),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, 0),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 0),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, 0),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 0),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, -1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, -1),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, -1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, -1),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 1),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 1),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 0),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 0),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 0),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 0),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, -1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, -1),
                      JzKet(S.Half, S.Half),
                  )
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, -1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, -1),
                      JzKet(S.Half, Rational(-1, 2)),
                  )
              )
          )
      )
      # Couple j1+j3=j13, j2+j4=j24, j13+j24=j
      # j1=1/2, j2=1/2, j3=1/2, j4=1/2
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      # j1=1/2, j2=1/2, j3=1, j4=1/2
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, 1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 1),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, 1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 1),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, 0),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 0),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, 0),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 0),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, -1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, -1),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, S.Half),
          JzKet(1, -1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, S.Half),
                      JzKet(1, -1),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 1),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 1),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 0),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 0),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 0),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 0),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, -1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, -1),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, S.Half),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, -1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, S.Half),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, -1),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, 1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 1),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, 1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 1),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, 0),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 0),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, 0),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, 0),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, -1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, -1),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, S.Half),
          JzKet(1, -1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, S.Half),
                      JzKet(1, -1),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 1),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 1),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 0),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 0),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, 0),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, 0),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, -1),
          JzKet(S.Half, S.Half),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, -1),
                      JzKet(S.Half, S.Half),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
      assert TensorProduct(
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(S.Half, Rational(-1, 2)),
          JzKet(1, -1),
          JzKet(S.Half, Rational(-1, 2)),
      ) == expand(
          uncouple(
              couple(
                  TensorProduct(
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(S.Half, Rational(-1, 2)),
                      JzKet(1, -1),
                      JzKet(S.Half, Rational(-1, 2)),
                  ),
                  ((1, 3), (2, 4), (1, 2)),
              )
          )
      )
  
imports: from sympy.concrete.summations import Sum
  from sympy.core.function import expand
  from sympy.core.numbers import I, Rational, pi
  from sympy.core.singleton import S
  from sympy.core.symbol import symbols
  from sympy.functions.elementary.exponential import exp
  from sympy.functions.elementary.miscellaneous import sqrt
  from sympy.functions.elementary.trigonometric import cos, sin
  from sympy.matrices.dense import Matrix
  from sympy.abc import alpha, beta, gamma, j, m
  from sympy.physics.quantum import hbar, represent, Commutator, InnerProduct
  from sympy.physics.quantum.qapply import qapply
  from sympy.physics.quantum.tensorproduct import TensorProduct
  from sympy.physics.quantum.cg import CG
  from sympy.physics.quantum.spin import Jx, Jy, Jz, Jplus, Jminus, J2, JxBra, JyBra, JzBra, JxKet, JyKet, JzKet, JxKetCoupled, JyKetCoupled, JzKetCoupled, couple, uncouple, Rotation, WignerD
  from sympy.testing.pytest import raises, slow
label_desc: Use image node_id 14 for calling a global function with example usage: test_uncouple_4_coupled_states() without return types