docs: def eval(self, valuation=None, trace=None):
          """
          This method should be always called by subclasses
          :param valuation
          :param trace
          :return: Arguments evaluation
          """
          args2 = []
          for a in self.args:
              if isinstance(a, Function) or isinstance(a, IPredicate):
                  args2.append(Constant(a.eval(valuation=valuation, trace=trace)))
  
              elif isinstance(a, Variable):
                  found = False
                  for v in valuation:
                      if str(v.var) == a.name:
                          args2.append(Constant(str(v.value.name)))
                          found = True
                          break
                  if not found:
                      raise Exception("IPredicate instantiation failed : missing vars")
              else:
                  args2.append(Constant(a))
  
          return args2