public static boolean helpEquivalentPropositionsP(Proposition self, Proposition other, KeyValueMap mapping, boolean ignorelastargP) {
    if (self == other) {
      return (true);
    }
    if (!(self.kind == other.kind)) {
      return (false);
    }
    { Keyword testValue000 = self.kind;

      if ((testValue000 == Logic.KWD_AND) ||
          ((testValue000 == Logic.KWD_OR) ||
           (testValue000 == Logic.KWD_EQUIVALENT))) {
        return (Proposition.equivalentCommutativePropositionsP(self, other, mapping));
      }
      else {
        { Keyword testValue001 = self.kind;

          if ((testValue001 == Logic.KWD_FORALL) ||
              (testValue001 == Logic.KWD_EXISTS)) {
            { Vector iovars1 = ((Vector)(KeyValueList.dynamicSlotValue(self.dynamicSlots, Logic.SYM_LOGIC_IO_VARIABLES, null)));
              Vector iovars2 = ((Vector)(KeyValueList.dynamicSlotValue(other.dynamicSlots, Logic.SYM_LOGIC_IO_VARIABLES, null)));

              if (!(iovars1.length() == iovars2.length())) {
                return (false);
              }
              if (mapping == null) {
                mapping = KeyValueMap.newKeyValueMap();
              }
              { PatternVariable v1 = null;
                Vector vector000 = iovars1;
                int index000 = 0;
                int length000 = vector000.length();
                PatternVariable v2 = null;
                Vector vector001 = iovars2;
                int index001 = 0;
                int length001 = vector001.length();

                for (;(index000 < length000) &&
                          (index001 < length001); index000 = index000 + 1, index001 = index001 + 1) {
                  v1 = ((PatternVariable)((vector000.theArray)[index000]));
                  v2 = ((PatternVariable)((vector001.theArray)[index001]));
                  mapping.insertAt(v1, v2);
                }
              }
            }
          }
          else {
          }
        }
        { Vector selfargs = self.arguments;
          Vector otherargs = other.arguments;

          { boolean testValue002 = false;

            testValue002 = self.operator == other.operator;
            if (testValue002) {
              { boolean alwaysP000 = true;

                { Stella_Object arg1 = null;
                  Vector vector002 = selfargs;
                  int index002 = 0;
                  int length002 = vector002.length();
                  Stella_Object arg2 = null;
                  Vector vector003 = otherargs;
                  int index003 = 0;
                  int length003 = vector003.length();
                  int i = Stella.NULL_INTEGER;
                  int iter000 = 2;
                  int upperBound000 = (ignorelastargP ? selfargs.length() : Stella.NULL_INTEGER);
                  boolean unboundedP000 = upperBound000 == Stella.NULL_INTEGER;

                  loop001 : for (;(index002 < length002) &&
                            ((index003 < length003) &&
                             (unboundedP000 ||
                              (iter000 <= upperBound000))); 
                        index002 = index002 + 1,
                        index003 = index003 + 1,
                        iter000 = iter000 + 1) {
                    arg1 = (vector002.theArray)[index002];
                    arg2 = (vector003.theArray)[index003];
                    i = iter000;
                    if (!Logic.equivalentFormulaeP(arg1, arg2, mapping)) {
                      alwaysP000 = false;
                      break loop001;
                    }
                  }
                }
                testValue002 = alwaysP000;
              }
              if (testValue002) {
                testValue002 = selfargs.length() == otherargs.length();
              }
            }
            if (!testValue002) {
              testValue002 = (mapping != null) &&
                  ((self.operator == Logic.SGT_PL_KERNEL_KB_HOLDS) &&
                   Proposition.equivalentHoldsPropositionP(self, other, mapping));
            }
            { boolean value000 = testValue002;

              return (value000);
            }
          }
        }
      }
    }
  }