public static void inferTypesFromOneProposition(Proposition proposition, KeyValueList table, Cons visiblevars) {
    if (proposition.arguments.length() == 0) {
      return;
    }
    { Vector arguments = proposition.arguments;
      Stella_Object firstarg = (arguments.theArray)[0];

      { Keyword testValue000 = proposition.kind;

        if (testValue000 == Logic.KWD_ISA) {
          if (Stella_Object.isaP(firstarg, Logic.SGT_LOGIC_PATTERN_VARIABLE)) {
            PatternVariable.addVariableType(((PatternVariable)(firstarg)), ((Surrogate)(proposition.operator)), table, visiblevars);
          }
        }
        else if ((testValue000 == Logic.KWD_PREDICATE) ||
            (testValue000 == Logic.KWD_FUNCTION)) {
          { Stella_Object predicate = null;

            { Surrogate testValue001 = Stella_Object.safePrimaryType(firstarg);

              if (Surrogate.subtypeOfP(testValue001, Logic.SGT_LOGIC_PATTERN_VARIABLE)) {
                { PatternVariable firstarg000 = ((PatternVariable)(firstarg));

                  { List types = ((List)(table.lookup(firstarg000)));

                    if (types != null) {
                      predicate = Logic.inferPredicateFromOperatorAndTypes(proposition.operator, types);
                    }
                  }
                }
              }
              else if (Surrogate.subtypeOfSurrogateP(testValue001)) {
                { Surrogate firstarg000 = ((Surrogate)(firstarg));

                  { Stella_Object value = firstarg000.surrogateValue;
                    List types = List.newList();

                    if ((value != null) &&
                        Stella_Object.isaP(value, Logic.SGT_LOGIC_LOGIC_OBJECT)) {
                      { NamedDescription d = null;
                        Cons iter000 = Logic.allAssertedTypes(value);
                        Cons collect000 = null;

                        for (;!(iter000 == Stella.NIL); iter000 = iter000.rest) {
                          d = ((NamedDescription)(iter000.value));
                          if (collect000 == null) {
                            {
                              collect000 = Cons.cons(d.surrogateValueInverse, Stella.NIL);
                              if (types.theConsList == Stella.NIL) {
                                types.theConsList = collect000;
                              }
                              else {
                                Cons.addConsToEndOfConsList(types.theConsList, collect000);
                              }
                            }
                          }
                          else {
                            {
                              collect000.rest = Cons.cons(d.surrogateValueInverse, Stella.NIL);
                              collect000 = collect000.rest;
                            }
                          }
                        }
                      }
                      types = Logic.mostSpecificTypes(types);
                      predicate = Logic.inferPredicateFromOperatorAndTypes(proposition.operator, types);
                    }
                  }
                }
              }
              else {
                { GeneralizedSymbol operator = proposition.operator;

                  if (Stella_Object.isaP(operator, Logic.SGT_STELLA_SURROGATE) &&
                      Stella_Object.isaP(((Surrogate)(operator)).surrogateValue, Logic.SGT_STELLA_SLOT)) {
                    predicate = ((Slot)(((Surrogate)(operator)).surrogateValue));
                  }
                }
              }
            }
            if (predicate != null) {
              { Surrogate testValue002 = Stella_Object.safePrimaryType(predicate);

                if (Surrogate.subtypeOfP(testValue002, Logic.SGT_LOGIC_NAMED_DESCRIPTION)) {
                  { NamedDescription predicate000 = ((NamedDescription)(predicate));

                    if (predicate000.ioVariableTypes != null) {
                      { Stella_Object arg = null;
                        Vector vector000 = arguments;
                        int index000 = 0;
                        int length000 = vector000.length();
                        Surrogate type = null;
                        Cons iter001 = predicate000.ioVariableTypes.theConsList;

                        for (;(index000 < length000) &&
                                  (!(iter001 == Stella.NIL)); index000 = index000 + 1, iter001 = iter001.rest) {
                          arg = (vector000.theArray)[index000];
                          type = ((Surrogate)(iter001.value));
                          if (Stella_Object.isaP(arg, Logic.SGT_LOGIC_PATTERN_VARIABLE)) {
                            PatternVariable.addVariableType(((PatternVariable)(arg)), type, table, visiblevars);
                          }
                        }
                      }
                    }
                    else {
                    }
                  }
                }
                else if (Surrogate.subtypeOfP(testValue002, Logic.SGT_STELLA_SLOT)) {
                  { Slot predicate000 = ((Slot)(predicate));

                    { Stella_Object arg = null;
                      Vector vector001 = arguments;
                      int index001 = 0;
                      int length001 = vector001.length();
                      Surrogate columntype = null;
                      Cons iter002 = Logic.slotColumnTypes(predicate000, arguments.length());

                      for (;(index001 < length001) &&
                                (!(iter002 == Stella.NIL)); index001 = index001 + 1, iter002 = iter002.rest) {
                        arg = (vector001.theArray)[index001];
                        columntype = ((Surrogate)(iter002.value));
                        if (Stella_Object.isaP(arg, Logic.SGT_LOGIC_PATTERN_VARIABLE)) {
                          PatternVariable.addVariableType(((PatternVariable)(arg)), columntype, table, visiblevars);
                        }
                      }
                    }
                  }
                }
                else if (Surrogate.subtypeOfP(testValue002, Logic.SGT_LOGIC_LOGIC_OBJECT)) {
                  { LogicObject predicate000 = ((LogicObject)(predicate));

                  }
                }
                else {
                  { OutputStringStream stream000 = OutputStringStream.newOutputStringStream();

                    stream000.nativeStream.print("`" + testValue002 + "' is not a valid case option");
                    throw ((StellaException)(StellaException.newStellaException(stream000.theStringReader()).fillInStackTrace()));
                  }
                }
              }
            }
          }
        }
        else if (testValue000 == Logic.KWD_EQUIVALENT) {
          { Stella_Object secondarg = (arguments.theArray)[1];

            if (Stella_Object.isaP(firstarg, Logic.SGT_LOGIC_PATTERN_VARIABLE)) {
              if (Stella_Object.isaP(secondarg, Logic.SGT_LOGIC_PATTERN_VARIABLE)) {
                { Stella_Object t = null;
                  Cons iter003 = List.mapNullToNilList(((List)(table.lookup(((PatternVariable)(secondarg)))))).theConsList;

                  for (;!(iter003 == Stella.NIL); iter003 = iter003.rest) {
                    t = iter003.value;
                    PatternVariable.addVariableType(((PatternVariable)(firstarg)), ((Surrogate)(t)), table, visiblevars);
                  }
                }
              }
              else {
                PatternVariable.addVariableType(((PatternVariable)(firstarg)), Logic.logicalType(secondarg), table, visiblevars);
              }
            }
            if (Stella_Object.isaP(secondarg, Logic.SGT_LOGIC_PATTERN_VARIABLE)) {
              if (Stella_Object.isaP(firstarg, Logic.SGT_LOGIC_PATTERN_VARIABLE)) {
                { Stella_Object t = null;
                  Cons iter004 = List.mapNullToNilList(((List)(table.lookup(((PatternVariable)(firstarg)))))).theConsList;

                  for (;!(iter004 == Stella.NIL); iter004 = iter004.rest) {
                    t = iter004.value;
                    PatternVariable.addVariableType(((PatternVariable)(secondarg)), ((Surrogate)(t)), table, visiblevars);
                  }
                }
              }
              else {
                PatternVariable.addVariableType(((PatternVariable)(secondarg)), Logic.logicalType(firstarg), table, visiblevars);
              }
            }
          }
        }
        else {
        }
      }
    }
  }