code: def test_properties():
      R = QQ.old_poly_ring(x, y)
      F = R.free_module(2)
      h = homomorphism(F, F, [[x, 0], [y, 0]])
      assert h.kernel() == F.submodule([-y, x])
      assert h.image() == F.submodule([x, 0], [y, 0])
      assert not h.is_injective()
      assert not h.is_surjective()
      assert h.restrict_codomain(h.image()).is_surjective()
      assert h.restrict_domain(F.submodule([1, 0])).is_injective()
      assert (
          h.quotient_domain(h.kernel())
          .restrict_codomain(h.image())
          .is_isomorphism()
      )
  
      R2 = QQ.old_poly_ring(x, y, order=(("lex", x), ("ilex", y))) / [
          x**2 + 1
      ]
      F = R2.free_module(2)
      h = homomorphism(F, F, [[x, 0], [y, y + 1]])
      assert h.is_isomorphism()
  
file_path: sympy/sympy/polys/agca/tests/test_homomorphisms.py
imports: from sympy.core.singleton import S
  from sympy.polys.domains.rationalfield import QQ
  from sympy.abc import x, y
  from sympy.polys.agca import homomorphism
  from sympy.testing.pytest import raises
label_desc: Use image node_id 4 for calling a global function with example usage: test_properties() without return types