code: def checksol(f, symbol, sol=None, **flags):
      """
      Checks whether sol is a solution of equation f == 0.
  
      Explanation
      ===========
  
      Input can be either a single symbol and corresponding value
      or a dictionary of symbols and values. When given as a dictionary
      and flag ``simplify=True``, the values in the dictionary will be
      simplified. *f* can be a single equation or an iterable of equations.
      A solution must satisfy all equations in *f* to be considered valid;
      if a solution does not satisfy any equation, False is returned; if one or
      more checks are inconclusive (and none are False) then None is returned.
  
      Examples
      ========
  
      >>> from sympy import checksol, symbols
      >>> x, y = symbols('x,y')
      >>> checksol(x**4 - 1, x, 1)
      True
      >>> checksol(x**4 - 1, x, 0)
      False
      >>> checksol(x**2 + y**2 - 5**2, {x: 3, y: 4})
      True
  
      To check if an expression is zero using ``checksol()``, pass it
      as *f* and send an empty dictionary for *symbol*:
  
      >>> checksol(x**2 + x - x*(x + 1), {})
      True
  
      None is returned if ``checksol()`` could not conclude.
  
      flags:
          'numerical=True (default)'
             do a fast numerical check if ``f`` has only one symbol.
          'minimal=True (default is False)'
             a very fast, minimal testing.
          'warn=True (default is False)'
             show a warning if checksol() could not conclude.
          'simplify=True (default)'
             simplify solution before substituting into function and
             simplify the function before trying specific simplifications
          'force=True (default is False)'
             make positive all symbols without assumptions regarding sign.
  
      """
      from sympy.physics.units import Unit
  
      minimal = flags.get("minimal", False)
  
      if sol is not None:
          sol = {symbol: sol}
      elif isinstance(symbol, dict):
          sol = symbol
      else:
          msg = "Expecting (sym, val) or ({sym: val}, None) but got (%s, %s)"
          raise ValueError(msg % (symbol, sol))
  
      if iterable(f):
          if not f:
              raise ValueError("no functions to check")
          rv = True
          for fi in f:
              check = checksol(fi, sol, **flags)
              if check:
                  continue
              if check is False:
                  return False
              rv = None  # don't return, wait to see if there's a False
          return rv
  
      f = _sympify(f)
  
      if f.is_number:
          return f.is_zero
  
      if isinstance(f, Poly):
          f = f.as_expr()
      elif isinstance(f, (Eq, Ne)):
          if f.rhs in (S.true, S.false):
              f = f.reversed
          B, E = f.args
          if isinstance(B, BooleanAtom):
              f = f.subs(sol)
              if not f.is_Boolean:
                  return
          elif isinstance(f, Eq):
              f = Add(f.lhs, -f.rhs, evaluate=False)
  
      if isinstance(f, BooleanAtom):
          return bool(f)
      elif not f.is_Relational and not f:
          return True
  
      illegal = set(_illegal)
      if any(sympify(v).atoms() & illegal for k, v in sol.items()):
          return False
  
      attempt = -1
      numerical = flags.get("numerical", True)
      while 1:
          attempt += 1
          if attempt == 0:
              val = f.subs(sol)
              if isinstance(val, Mul):
                  val = val.as_independent(Unit)[0]
              if val.atoms() & illegal:
                  return False
          elif attempt == 1:
              if not val.is_number:
                  if not val.is_constant(
                      *list(sol.keys()), simplify=not minimal
                  ):
                      return False
                  # there are free symbols -- simple expansion might work
                  _, val = val.as_content_primitive()
                  val = _mexpand(
                      val.as_numer_denom()[0], recursive=True
                  )
          elif attempt == 2:
              if minimal:
                  return
              if flags.get("simplify", True):
                  for k in sol:
                      sol[k] = simplify(sol[k])
              # start over without the failed expanded form, possibly
              # with a simplified solution
              val = simplify(f.subs(sol))
              if flags.get("force", True):
                  val, reps = posify(val)
                  # expansion may work now, so try again and check
                  exval = _mexpand(val, recursive=True)
                  if exval.is_number:
                      # we can decide now
                      val = exval
          else:
              # if there are no radicals and no functions then this can't be
              # zero anymore -- can it?
              pot = preorder_traversal(expand_mul(val))
              seen = set()
              saw_pow_func = False
              for p in pot:
                  if p in seen:
                      continue
                  seen.add(p)
                  if p.is_Pow and not p.exp.is_Integer:
                      saw_pow_func = True
                  elif p.is_Function:
                      saw_pow_func = True
                  elif isinstance(p, UndefinedFunction):
                      saw_pow_func = True
                  if saw_pow_func:
                      break
              if saw_pow_func is False:
                  return False
              if flags.get("force", True):
                  # don't do a zero check with the positive assumptions in place
                  val = val.subs(reps)
              nz = fuzzy_not(val.is_zero)
              if nz is not None:
                  # issue 5673: nz may be True even when False
                  # so these are just hacks to keep a false positive
                  # from being returned
  
                  # HACK 1: LambertW (issue 5673)
                  if val.is_number and val.has(LambertW):
                      # don't eval this to verify solution since if we got here,
                      # numerical must be False
                      return None
  
                  # add other HACKs here if necessary, otherwise we assume
                  # the nz value is correct
                  return not nz
              break
          if val.is_Rational:
              return val == 0
          if numerical and val.is_number:
              return (abs(val.n(18).n(12, chop=True)) < 1e-9) is S.true
  
      if flags.get("warn", False):
          warnings.warn(
              "\n\tWarning: could not verify solution %s." % sol
          )
  
imports: from __future__ import annotations
  from sympy.core import S, Add, Symbol, Dummy, Expr, Mul
  from sympy.core.assumptions import check_assumptions
  from sympy.core.exprtools import factor_terms
  from sympy.core.function import expand_mul, expand_log, Derivative, AppliedUndef, UndefinedFunction, nfloat, Function, expand_power_exp, _mexpand, expand, expand_func
  from sympy.core.logic import fuzzy_not
  from sympy.core.numbers import Float, Rational, _illegal
  from sympy.core.intfunc import integer_log, ilcm
  from sympy.core.power import Pow
  from sympy.core.relational import Eq, Ne
  from sympy.core.sorting import ordered, default_sort_key
  from sympy.core.sympify import sympify, _sympify
  from sympy.core.traversal import preorder_traversal
  from sympy.logic.boolalg import And, BooleanAtom
  from sympy.functions import log, exp, LambertW, cos, sin, tan, acos, asin, atan, Abs, re, im, arg, sqrt, atan2
  from sympy.functions.combinatorial.factorials import binomial
  from sympy.functions.elementary.hyperbolic import HyperbolicFunction
  from sympy.functions.elementary.piecewise import piecewise_fold, Piecewise
  from sympy.functions.elementary.trigonometric import TrigonometricFunction
  from sympy.integrals.integrals import Integral
  from sympy.ntheory.factor_ import divisors
  from sympy.simplify import simplify, collect, powsimp, posify, powdenest, nsimplify, denom, logcombine, sqrtdenest, fraction, separatevars
  from sympy.simplify.sqrtdenest import sqrt_depth
  from sympy.simplify.fu import TR1, TR2i, TR10, TR11
  from sympy.strategies.rl import rebuild
  from sympy.matrices.exceptions import NonInvertibleMatrixError
  from sympy.matrices import Matrix, zeros
  from sympy.polys import roots, cancel, factor, Poly
  from sympy.polys.solvers import sympy_eqs_to_ring, solve_lin_sys
  from sympy.polys.polyerrors import GeneratorsNeeded, PolynomialError
  from sympy.polys.polytools import gcd
  from sympy.utilities.lambdify import lambdify
  from sympy.utilities.misc import filldedent, debugf
  from sympy.utilities.iterables import connected_components, generate_bell, uniq, iterable, is_sequence, subsets, flatten, sift
  from sympy.utilities.decorator import conserve_mpmath_dps
  from mpmath import findroot
  from sympy.solvers.polysys import solve_poly_system
  from types import GeneratorType
  from collections import defaultdict
  from itertools import combinations, product
  import warnings
  from sympy.solvers.bivariate import bivariate_type, _solve_lambert, _filtered_gens
label_desc: Use image node_id 5 for calling a global function with example usage: checksol(f, symbol, sol) and returns: rv, f, bool, False, True, unknown, unknown, False, False, False, False, unknown, None