Full Code of HarvardPL/formulog for AI

master e1e7f6ffe3b7 cached
664 files
1.4 MB
399.4k tokens
3392 symbols
1 requests
Download .txt
Showing preview only (1,608K chars total). Download the full file or copy to clipboard to get everything.
Repository: HarvardPL/formulog
Branch: master
Commit: e1e7f6ffe3b7
Files: 664
Total size: 1.4 MB

Directory structure:
gitextract_eqja_ilo/

├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── maven.yml
│       ├── pages.yml
│       └── submit-deps.yml
├── .gitignore
├── Dockerfile
├── LICENSE.txt
├── README.md
├── changelog.md
├── docs/
│   ├── Gemfile
│   ├── _config.yml
│   ├── eval_modes/
│   │   ├── compile.md
│   │   ├── eager.md
│   │   ├── index.md
│   │   ├── options.md
│   │   └── smt.md
│   ├── index.md
│   ├── lang_ref/
│   │   ├── goal_directed_eval.md
│   │   ├── index.md
│   │   ├── lang_basics.md
│   │   ├── logical_formulas.md
│   │   └── program_safety.md
│   ├── pubs.md
│   ├── starting.md
│   └── tutorial/
│       └── index.md
├── examples/
│   ├── greeting.flg
│   ├── liquid_types.flg
│   ├── symeval.flg
│   └── tutorial.flg
├── license-header
├── misc/
│   └── flg.vim
├── pom.xml
└── src/
    ├── main/
    │   ├── antlr4/
    │   │   └── edu/
    │   │       └── harvard/
    │   │           └── seas/
    │   │               └── pl/
    │   │                   └── formulog/
    │   │                       └── parsing/
    │   │                           └── generated/
    │   │                               └── Formulog.g4
    │   ├── java/
    │   │   └── edu/
    │   │       └── harvard/
    │   │           └── seas/
    │   │               └── pl/
    │   │                   └── formulog/
    │   │                       ├── Configuration.java
    │   │                       ├── FormulogTester.java
    │   │                       ├── Main.java
    │   │                       ├── PrintPreference.java
    │   │                       ├── ast/
    │   │                       │   ├── AbstractRule.java
    │   │                       │   ├── AbstractTerm.java
    │   │                       │   ├── BasicProgram.java
    │   │                       │   ├── BasicRule.java
    │   │                       │   ├── BindingType.java
    │   │                       │   ├── BoolTerm.java
    │   │                       │   ├── ComplexLiteral.java
    │   │                       │   ├── ComplexLiterals.java
    │   │                       │   ├── Constructor.java
    │   │                       │   ├── Constructors.java
    │   │                       │   ├── Expr.java
    │   │                       │   ├── Exprs.java
    │   │                       │   ├── FP32.java
    │   │                       │   ├── FP64.java
    │   │                       │   ├── Fold.java
    │   │                       │   ├── FunctionCallFactory.java
    │   │                       │   ├── Functor.java
    │   │                       │   ├── I32.java
    │   │                       │   ├── I64.java
    │   │                       │   ├── LetFunExpr.java
    │   │                       │   ├── Literal.java
    │   │                       │   ├── MatchClause.java
    │   │                       │   ├── MatchExpr.java
    │   │                       │   ├── Model.java
    │   │                       │   ├── NestedFunctionDef.java
    │   │                       │   ├── OpaqueSet.java
    │   │                       │   ├── Primitive.java
    │   │                       │   ├── Program.java
    │   │                       │   ├── Rule.java
    │   │                       │   ├── SmtLibTerm.java
    │   │                       │   ├── StringTerm.java
    │   │                       │   ├── Term.java
    │   │                       │   ├── Terms.java
    │   │                       │   ├── UnificationPredicate.java
    │   │                       │   ├── UserPredicate.java
    │   │                       │   └── Var.java
    │   │                       ├── codegen/
    │   │                       │   ├── CodeGen.java
    │   │                       │   ├── CodeGenContext.java
    │   │                       │   ├── CodeGenException.java
    │   │                       │   ├── CodeGenUtil.java
    │   │                       │   ├── DeltaFirstQueryPlanner.java
    │   │                       │   ├── FuncsHpp.java
    │   │                       │   ├── FunctorCodeGen.java
    │   │                       │   ├── MainCpp.java
    │   │                       │   ├── MatchCodeGen.java
    │   │                       │   ├── NopQueryPlanner.java
    │   │                       │   ├── PatternMatchTree.java
    │   │                       │   ├── QueryPlanner.java
    │   │                       │   ├── RuleTranslator.java
    │   │                       │   ├── SmtParserCpp.java
    │   │                       │   ├── SmtShimCpp.java
    │   │                       │   ├── SouffleCodeGen.java
    │   │                       │   ├── SymbolCpp.java
    │   │                       │   ├── SymbolHpp.java
    │   │                       │   ├── TemplateSrcFile.java
    │   │                       │   ├── TermCodeGen.java
    │   │                       │   ├── TermCpp.java
    │   │                       │   ├── TypeCodeGen.java
    │   │                       │   ├── TypeCpp.java
    │   │                       │   └── ast/
    │   │                       │       ├── cpp/
    │   │                       │       │   ├── CppAccess.java
    │   │                       │       │   ├── CppBaseTerm.java
    │   │                       │       │   ├── CppBinop.java
    │   │                       │       │   ├── CppBlock.java
    │   │                       │       │   ├── CppCast.java
    │   │                       │       │   ├── CppConst.java
    │   │                       │       │   ├── CppCtor.java
    │   │                       │       │   ├── CppDecl.java
    │   │                       │       │   ├── CppExpr.java
    │   │                       │       │   ├── CppExprFromString.java
    │   │                       │       │   ├── CppFor.java
    │   │                       │       │   ├── CppForEach.java
    │   │                       │       │   ├── CppFuncCall.java
    │   │                       │       │   ├── CppGoto.java
    │   │                       │       │   ├── CppIf.java
    │   │                       │       │   ├── CppLabel.java
    │   │                       │       │   ├── CppMethodCall.java
    │   │                       │       │   ├── CppNewArray.java
    │   │                       │       │   ├── CppNullptr.java
    │   │                       │       │   ├── CppReturn.java
    │   │                       │       │   ├── CppSeq.java
    │   │                       │       │   ├── CppStmt.java
    │   │                       │       │   ├── CppSubscript.java
    │   │                       │       │   ├── CppUnop.java
    │   │                       │       │   ├── CppVar.java
    │   │                       │       │   ├── CppVectorLiteral.java
    │   │                       │       │   └── CppWhile.java
    │   │                       │       └── souffle/
    │   │                       │           ├── SAtom.java
    │   │                       │           ├── SDestructorBody.java
    │   │                       │           ├── SExprBody.java
    │   │                       │           ├── SFunctorBody.java
    │   │                       │           ├── SFunctorCall.java
    │   │                       │           ├── SInfixBinaryOpAtom.java
    │   │                       │           ├── SInt.java
    │   │                       │           ├── SIntList.java
    │   │                       │           ├── SIntListType.java
    │   │                       │           ├── SIntType.java
    │   │                       │           ├── SLit.java
    │   │                       │           ├── SRule.java
    │   │                       │           ├── SRuleMode.java
    │   │                       │           ├── STerm.java
    │   │                       │           ├── SType.java
    │   │                       │           └── SVar.java
    │   │                       ├── db/
    │   │                       │   ├── BindingTypeArrayWrapper.java
    │   │                       │   ├── ExampleComparator.java
    │   │                       │   ├── IndexedFactDb.java
    │   │                       │   ├── IndexedFactDbBuilder.java
    │   │                       │   ├── MinChainCover.java
    │   │                       │   ├── MinIndex.java
    │   │                       │   ├── SortedIndexedFactDb.java
    │   │                       │   └── TupleComparatorGenerator.java
    │   │                       ├── eval/
    │   │                       │   ├── AbstractStratumEvaluator.java
    │   │                       │   ├── EagerStratumEvaluator.java
    │   │                       │   ├── EvalUtil.java
    │   │                       │   ├── Evaluation.java
    │   │                       │   ├── EvaluationException.java
    │   │                       │   ├── EvaluationResult.java
    │   │                       │   ├── IndexedRule.java
    │   │                       │   ├── PredicateFunctionSetter.java
    │   │                       │   ├── RoundBasedStratumEvaluator.java
    │   │                       │   ├── SemiNaiveEvaluation.java
    │   │                       │   ├── SemiNaiveRule.java
    │   │                       │   ├── SmtCallFinder.java
    │   │                       │   ├── StratumEvaluator.java
    │   │                       │   └── UncheckedEvaluationException.java
    │   │                       ├── functions/
    │   │                       │   ├── BuiltInFunctionDefFactory.java
    │   │                       │   ├── DummyFunctionDef.java
    │   │                       │   ├── FunctionDef.java
    │   │                       │   ├── FunctionDefManager.java
    │   │                       │   ├── OpaqueSetOps.java
    │   │                       │   ├── PredicateFunctionDef.java
    │   │                       │   ├── PrimitiveConversions.java
    │   │                       │   ├── RecordAccessor.java
    │   │                       │   └── UserFunctionDef.java
    │   │                       ├── magic/
    │   │                       │   ├── AdornedSymbol.java
    │   │                       │   ├── Adornments.java
    │   │                       │   └── MagicSetTransformer.java
    │   │                       ├── parsing/
    │   │                       │   ├── FactFileParser.java
    │   │                       │   ├── Identifier.java
    │   │                       │   ├── ParseException.java
    │   │                       │   ├── Parser.java
    │   │                       │   ├── ParsingContext.java
    │   │                       │   ├── ParsingUtil.java
    │   │                       │   ├── TermExtractor.java
    │   │                       │   ├── TopLevelParser.java
    │   │                       │   ├── TypeExtractor.java
    │   │                       │   ├── UncheckedParseException.java
    │   │                       │   ├── VariableCheckPass.java
    │   │                       │   └── VariableCheckPassException.java
    │   │                       ├── smt/
    │   │                       │   ├── AbstractSmtLibSolver.java
    │   │                       │   ├── BestMatchSmtManager.java
    │   │                       │   ├── BoolectorProcessFactory.java
    │   │                       │   ├── CallAndResetSolver.java
    │   │                       │   ├── CheckSatAssumingSolver.java
    │   │                       │   ├── Cvc4ProcessFactory.java
    │   │                       │   ├── DoubleCheckingSolver.java
    │   │                       │   ├── ExternalSolverProcessFactory.java
    │   │                       │   ├── NotThreadSafeQueueSmtManager.java
    │   │                       │   ├── PerThreadSmtManager.java
    │   │                       │   ├── PushPopNaiveSolver.java
    │   │                       │   ├── PushPopSolver.java
    │   │                       │   ├── QueueSmtManager.java
    │   │                       │   ├── SingleShotSolver.java
    │   │                       │   ├── SmtLibParser.java
    │   │                       │   ├── SmtLibShim.java
    │   │                       │   ├── SmtLibSolver.java
    │   │                       │   ├── SmtResult.java
    │   │                       │   ├── SmtStatus.java
    │   │                       │   ├── SmtStrategy.java
    │   │                       │   ├── YicesProcessFactory.java
    │   │                       │   └── Z3ProcessFactory.java
    │   │                       ├── symbols/
    │   │                       │   ├── AbstractSymbol.java
    │   │                       │   ├── AbstractTypedSymbol.java
    │   │                       │   ├── AbstractWrappedRelationSymbol.java
    │   │                       │   ├── BuiltInConstructorGetterSymbol.java
    │   │                       │   ├── BuiltInConstructorSymbol.java
    │   │                       │   ├── BuiltInConstructorTesterSymbol.java
    │   │                       │   ├── BuiltInFunctionSymbol.java
    │   │                       │   ├── BuiltInTypeSymbol.java
    │   │                       │   ├── ConstructorSymbol.java
    │   │                       │   ├── ConstructorSymbolImpl.java
    │   │                       │   ├── ConstructorSymbolType.java
    │   │                       │   ├── FunctionSymbol.java
    │   │                       │   ├── GlobalSymbolManager.java
    │   │                       │   ├── MutableRelationSymbol.java
    │   │                       │   ├── PredicateFunctionSymbol.java
    │   │                       │   ├── RecordSymbol.java
    │   │                       │   ├── RelationSymbol.java
    │   │                       │   ├── Symbol.java
    │   │                       │   ├── SymbolComparator.java
    │   │                       │   ├── SymbolManager.java
    │   │                       │   ├── TypeSymbol.java
    │   │                       │   ├── TypeSymbolImpl.java
    │   │                       │   ├── TypeSymbolType.java
    │   │                       │   ├── TypedSymbol.java
    │   │                       │   ├── WrappedRelationSymbol.java
    │   │                       │   └── parameterized/
    │   │                       │       ├── AbstractParameterizedSymbol.java
    │   │                       │       ├── BuiltInConstructorSymbolBase.java
    │   │                       │       ├── FunctorBase.java
    │   │                       │       ├── Param.java
    │   │                       │       ├── ParamKind.java
    │   │                       │       ├── ParameterizedConstructorSymbol.java
    │   │                       │       ├── ParameterizedSymbol.java
    │   │                       │       └── SymbolBase.java
    │   │                       ├── types/
    │   │                       │   ├── BuiltInTypes.java
    │   │                       │   ├── FunctorType.java
    │   │                       │   ├── IndexedType.java
    │   │                       │   ├── TypeAlias.java
    │   │                       │   ├── TypeChecker.java
    │   │                       │   ├── TypeException.java
    │   │                       │   ├── TypeManager.java
    │   │                       │   ├── Types.java
    │   │                       │   └── WellTypedProgram.java
    │   │                       ├── unification/
    │   │                       │   ├── EmptySubstitution.java
    │   │                       │   ├── OverwriteSubstitution.java
    │   │                       │   ├── SimpleSubstitution.java
    │   │                       │   ├── Substitution.java
    │   │                       │   └── Unification.java
    │   │                       ├── util/
    │   │                       │   ├── AbstractFJPTask.java
    │   │                       │   ├── CompositeIterable.java
    │   │                       │   ├── CountingFJP.java
    │   │                       │   ├── CountingFJPImpl.java
    │   │                       │   ├── Dataset.java
    │   │                       │   ├── DedupWorkList.java
    │   │                       │   ├── EnumerableThreadLocal.java
    │   │                       │   ├── ExceptionalFunction.java
    │   │                       │   ├── FunctorUtil.java
    │   │                       │   ├── IntArrayWrapper.java
    │   │                       │   ├── MockCountingFJP.java
    │   │                       │   ├── Pair.java
    │   │                       │   ├── SharedLong.java
    │   │                       │   ├── StackMap.java
    │   │                       │   ├── TodoException.java
    │   │                       │   ├── Triple.java
    │   │                       │   ├── UnionFind.java
    │   │                       │   ├── Util.java
    │   │                       │   └── sexp/
    │   │                       │       ├── SExp.java
    │   │                       │       ├── SExpAtom.java
    │   │                       │       ├── SExpException.java
    │   │                       │       ├── SExpLexer.java
    │   │                       │       ├── SExpList.java
    │   │                       │       ├── SExpParser.java
    │   │                       │       └── SExpToken.java
    │   │                       └── validating/
    │   │                           ├── FunctionDefValidation.java
    │   │                           ├── InvalidProgramException.java
    │   │                           ├── Stratifier.java
    │   │                           ├── Stratum.java
    │   │                           ├── ValidRule.java
    │   │                           └── ast/
    │   │                               ├── Assignment.java
    │   │                               ├── Check.java
    │   │                               ├── Destructor.java
    │   │                               ├── SimpleLiteral.java
    │   │                               ├── SimpleLiteralExnVisitor.java
    │   │                               ├── SimpleLiteralTag.java
    │   │                               ├── SimpleLiteralVisitor.java
    │   │                               ├── SimplePredicate.java
    │   │                               └── SimpleRule.java
    │   └── resources/
    │       └── codegen/
    │           ├── .gitignore
    │           ├── CMakeLists.txt
    │           └── src/
    │               ├── ConcurrentHashMap.hpp
    │               ├── Symbol.cpp
    │               ├── Symbol.hpp
    │               ├── Term.cpp
    │               ├── Term.hpp
    │               ├── Tuple.hpp
    │               ├── Type.cpp
    │               ├── Type.hpp
    │               ├── formulog.dl
    │               ├── funcs.hpp
    │               ├── functors.cpp
    │               ├── functors.h
    │               ├── globals.h
    │               ├── main.cpp
    │               ├── parser.cpp
    │               ├── parser.hpp
    │               ├── set.cpp
    │               ├── set.hpp
    │               ├── smt_parser.cpp
    │               ├── smt_parser.hpp
    │               ├── smt_shim.cpp
    │               ├── smt_shim.h
    │               ├── smt_solver.cpp
    │               ├── smt_solver.h
    │               └── time.hpp
    └── test/
        ├── java/
        │   └── edu/
        │       └── harvard/
        │           └── seas/
        │               └── pl/
        │                   └── formulog/
        │                       ├── codegen/
        │                       │   ├── CodeGenTester.java
        │                       │   ├── CompiledEagerEvaluationTest.java
        │                       │   ├── CompiledEagerMagicSetTest.java
        │                       │   ├── CompiledSemiNaiveEvaluationTest.java
        │                       │   ├── CompiledSemiNaiveMagicSetTest.java
        │                       │   └── NopTester.java
        │                       ├── eval/
        │                       │   ├── AbstractEvaluationTest.java
        │                       │   ├── AbstractTester.java
        │                       │   ├── CommonEvaluationTest.java
        │                       │   ├── EagerSemiNaiveEvaluationTest.java
        │                       │   ├── InterpretedSemiNaiveTester.java
        │                       │   ├── SemiNaiveEvaluationTest.java
        │                       │   └── Tester.java
        │                       ├── magic/
        │                       │   ├── CommonMagicSetTest.java
        │                       │   ├── EagerSemiNaiveMagicSetTest.java
        │                       │   └── SemiNaiveMagicSetTest.java
        │                       ├── parsing/
        │                       │   └── ParsingTest.java
        │                       ├── types/
        │                       │   └── TypeCheckingTest.java
        │                       └── validating/
        │                           ├── SemiNaiveValidatingTest.java
        │                           └── ValidatingTest.java
        └── resources/
            ├── test001_ok.flg
            ├── test002_ok.flg
            ├── test003_ok.flg
            ├── test004_ok.flg
            ├── test005_ok.flg
            ├── test006_ok.flg
            ├── test007_ok.flg
            ├── test008_ok.flg
            ├── test009_ok.flg
            ├── test010_ok.flg
            ├── test011_ok.flg
            ├── test012_bd.flg
            ├── test013_ok.flg
            ├── test014_ok.flg
            ├── test015_ok.flg
            ├── test016_ok.flg
            ├── test017_ok.flg
            ├── test018_ok.flg
            ├── test019_ok.flg
            ├── test020_ok.flg
            ├── test021_ok.flg
            ├── test022_ok.flg
            ├── test023_ok.flg
            ├── test024_ok.flg
            ├── test025_bd.flg
            ├── test026_bd.flg
            ├── test027_ok.flg
            ├── test028_ok.flg
            ├── test029_ok.flg
            ├── test030_ok.flg
            ├── test031_ok.flg
            ├── test032_ok.flg
            ├── test033_ok.flg
            ├── test034_ok.flg
            ├── test035_ok.flg
            ├── test036_ok.flg
            ├── test037_ok.flg
            ├── test038_ok.flg
            ├── test039_ok.flg
            ├── test040_ok.flg
            ├── test041_ok.flg
            ├── test042_ok.flg
            ├── test043_ok.flg
            ├── test044_ok.flg
            ├── test045_ok.flg
            ├── test046_ok.flg
            ├── test047_ok.flg
            ├── test048_ok.flg
            ├── test049_ok.flg
            ├── test050_bd.flg
            ├── test051_bd.flg
            ├── test052_bd.flg
            ├── test053_ok.flg
            ├── test054_ok.flg
            ├── test055_bd.flg
            ├── test056_ok.flg
            ├── test057_ok.flg
            ├── test058_ok.flg
            ├── test059_ok.flg
            ├── test060_ok.flg
            ├── test061_ok.flg
            ├── test062_ok.flg
            ├── test063_ok.flg
            ├── test064_ok.flg
            ├── test065_ok.flg
            ├── test066_ok.flg
            ├── test067_ok.flg
            ├── test068_ok.flg
            ├── test069_ok.flg
            ├── test070_ok.flg
            ├── test071_ok.flg
            ├── test072_ok.flg
            ├── test073_ok.flg
            ├── test074_ok.flg
            ├── test075_ok.flg
            ├── test076_ok.flg
            ├── test077_ok.flg
            ├── test078_ok.flg
            ├── test079_ok.flg
            ├── test080_bd.flg
            ├── test081_ok.flg
            ├── test082_ok.flg
            ├── test083_ok.flg
            ├── test084_ok.flg
            ├── test085_ok.flg
            ├── test086_ok.flg
            ├── test087_ok.flg
            ├── test088_ok.flg
            ├── test089_ok.flg
            ├── test090_ok.flg
            ├── test091_bd.flg
            ├── test092_ok.flg
            ├── test093_ok.flg
            ├── test094_ok.flg
            ├── test095_ok.flg
            ├── test096_ok.flg
            ├── test097_ok.flg
            ├── test098_bd.flg
            ├── test099_ok.flg
            ├── test100_ok.flg
            ├── test101_ok.flg
            ├── test102_ok.flg
            ├── test103_ok.flg
            ├── test104_ok.flg
            ├── test105_ok.flg
            ├── test106_ok.flg
            ├── test107_ok.flg
            ├── test108_ok.flg
            ├── test109_ok.flg
            ├── test110_ok.flg
            ├── test111_ok.flg
            ├── test112_ok.flg
            ├── test113_ok.flg
            ├── test114_ok.flg
            ├── test115_ok.flg
            ├── test116_ok.flg
            ├── test117_ok.flg
            ├── test118_bd.flg
            ├── test119_ok.flg
            ├── test120_ok.flg
            ├── test121_ok.flg
            ├── test122_ok.flg
            ├── test123_ok.flg
            ├── test124_ok.flg
            ├── test125_ok.flg
            ├── test126_ok.flg
            ├── test127_ok.flg
            ├── test128_ok.flg
            ├── test129_ok.flg
            ├── test130_bd.flg
            ├── test131_bd.flg
            ├── test132_bd.flg
            ├── test133_ok.flg
            ├── test134_ok.flg
            ├── test135_ok.flg
            ├── test136_ok.flg
            ├── test137_ok.flg
            ├── test138_ok.flg
            ├── test139_ok.flg
            ├── test140_ok.flg
            ├── test141_ok.flg
            ├── test142_ok.flg
            ├── test143_ok.flg
            ├── test144_ok.flg
            ├── test145_ok.flg
            ├── test146_ok.flg
            ├── test147_ok.flg
            ├── test148_ok.flg
            ├── test149_ok.flg
            ├── test150_ok.flg
            ├── test151_ok.flg
            ├── test152_ok.flg
            ├── test153_ok.flg
            ├── test154_ok.flg
            ├── test155_ok.flg
            ├── test156_ok.flg
            ├── test157_ok.flg
            ├── test158_ok.flg
            ├── test159_ok.flg
            ├── test160_ok.flg
            ├── test161_ok.flg
            ├── test162_ok.flg
            ├── test163_ok.flg
            ├── test164_ok.flg
            ├── test165_ok.flg
            ├── test166_ok.flg
            ├── test167_ok.flg
            ├── test168_ok.flg
            ├── test169_ok.flg
            ├── test170_ok.flg
            ├── test171_ok.flg
            ├── test172_ok.flg
            ├── test173_ok.flg
            ├── test174_ok.flg
            ├── test175_ok.flg
            ├── test176_ok.flg
            ├── test177_ok.flg
            ├── test178_ok.flg
            ├── test179_ok.flg
            ├── test180_ok.flg
            ├── test181_ok.flg
            ├── test182_ok.flg
            ├── test183_ok.flg
            ├── test184_ok.flg
            ├── test185_bd.flg
            ├── test186_ok.flg
            ├── test187_ok.flg
            ├── test188_bd.flg
            ├── test189_ok.flg
            ├── test190_ok.flg
            ├── test191_input/
            │   ├── complex_terms.tsv
            │   ├── names.tsv
            │   └── numbers.tsv
            ├── test191_ok.flg
            ├── test192_ok.flg
            ├── test193_ok.flg
            ├── test217_bd.flg
            ├── test218_bd.flg
            ├── test219_ok.flg
            ├── test220_ok.flg
            ├── test221_ok.flg
            ├── test222_ok.flg
            ├── test223_ok.flg
            ├── test224_ok.flg
            ├── test225_ok.flg
            ├── test226_ok.flg
            ├── test227_ok.flg
            ├── test228_ok.flg
            ├── test229_ok.flg
            ├── test230_ok.flg
            ├── test231_ok.flg
            ├── test232_ok.flg
            ├── test233_ok.flg
            ├── test234_ok.flg
            ├── test235_ok.flg
            ├── test236_ok.flg
            ├── test237_ok.flg
            ├── test238_ok.flg
            ├── test240_ok.flg
            ├── test241_ok.flg
            ├── test242_ok.flg
            ├── test243_ok.flg
            ├── test244_ok.flg
            ├── test245_ok.flg
            ├── test248_bd.flg
            ├── test249_ok.flg
            ├── test250_ok.flg
            ├── test251_bd.flg
            ├── test252_ok.flg
            ├── test253_ok.flg
            ├── test254_ok.flg
            ├── test255_bd.flg
            ├── test256_ok.flg
            ├── test257_ok.flg
            ├── test258_ok.flg
            ├── test259_ok.flg
            ├── test260_ok.flg
            ├── test261_ok.flg
            ├── test262_ok.flg
            ├── test263_ok.flg
            ├── test264_ok.flg
            ├── test265_ok.flg
            ├── test266_bd.flg
            ├── test267_ok.flg
            ├── test268_bd.flg
            ├── test269_bd.flg
            ├── test270_bd.flg
            ├── test271_bd.flg
            ├── test272_bd.flg
            ├── test273_ok.flg
            ├── test274_ok.flg
            ├── test275_ok.flg
            ├── test276_inputA/
            │   └── foo.tsv
            ├── test276_inputB/
            │   └── foo.tsv
            ├── test276_ok.flg
            ├── test277_ok.flg
            ├── test278_ok.flg
            ├── test279_ok.flg
            ├── test280_ok.flg
            ├── test281_ok.flg
            ├── test282_ok.flg
            ├── test283_ok.flg
            ├── test284_ok.flg
            ├── test285_ok.flg
            ├── test286_ok.flg
            ├── test287_ok.flg
            ├── test288_ok.flg
            ├── test289_ok.flg
            ├── test290_ok.flg
            ├── test291_ok.flg
            ├── test292_ok.flg
            ├── test293_ok.flg
            ├── test294_ok.flg
            ├── test295_bd.flg
            ├── test296_bd.flg
            ├── test297_ok.flg
            ├── test298_ok.flg
            ├── test299_ok.flg
            ├── test300_ok.flg
            ├── test301_ok.flg
            ├── test302_bd.flg
            ├── test303_ok.flg
            ├── test304_ok.flg
            ├── test305_ok.flg
            ├── test306_ok.flg
            ├── test307_ok.flg
            ├── test308_ok.flg
            ├── test309_ok.flg
            ├── test310_ok.flg
            ├── test311_ok.flg
            ├── test312_bd.flg
            ├── test313_bd.flg
            ├── test314_bd.flg
            ├── test315_bd.flg
            ├── test316_ok.flg
            ├── test317_ok.flg
            ├── test318_ok.flg
            ├── test319_ok.flg
            ├── test320_ok.flg
            ├── test321_ok.flg
            ├── test322_bd.flg
            ├── test323_ok.flg
            ├── test324_ok.flg
            ├── test325_ok.flg
            ├── test326_ok.flg
            ├── test327_bd.flg
            ├── test328_ok.flg
            ├── test329_ok.flg
            ├── test330_ok.flg
            ├── test331_ok.flg
            ├── test332_ok.flg
            ├── test333_bd.flg
            ├── test334_ok.flg
            ├── test335_bd.flg
            ├── test336_ok.flg
            ├── test337_ok.flg
            ├── test338_ok.flg
            ├── test339_ok.flg
            ├── test340_ok.flg
            ├── test341_bd.flg
            ├── test342_bd.flg
            ├── test343_bd.flg
            ├── test344_bd.flg
            └── test345_ok.flg

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "maven"
    directory: "/"
    schedule:
      interval: "weekly"


================================================
FILE: .github/workflows/maven.yml
================================================
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Java CI with Maven

on:
  push:
    branches: ["master"]
    paths:
      - "src/**"
      - "pom.xml"
  pull_request:
    branches: ["master"]
    paths:
      - "src/**"
      - "pom.xml"

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up Z3
      uses: pavpanchekha/setup-z3@v1.3
      with:
        version: '4.12.2'
    - name: Set up JDK 21
      uses: actions/setup-java@v3
      with:
        java-version: '21'
        distribution: 'temurin'
        cache: maven
    - name: Verify with Maven (includes building)
      run: mvn -B verify --file pom.xml



================================================
FILE: .github/workflows/pages.yml
================================================
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

# Sample workflow for building and deploying a Jekyll site to GitHub Pages
name: Deploy Jekyll site to Pages

on:
  push:
    branches: ["master"]
    paths: ["docs/**"]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow one concurrent deployment
concurrency:
  group: "pages"
  cancel-in-progress: true

jobs:
  # Build job
  build:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: docs
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.3' # Not needed with a .ruby-version file
          bundler-cache: true # runs 'bundle install' and caches installed gems automatically
          cache-version: 0 # Increment this number if you need to re-download cached gems
          working-directory: '${{ github.workspace }}/docs'
      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v5
      - name: Build with Jekyll
        # Outputs to the './_site' directory by default
        run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
        env:
          JEKYLL_ENV: production
      - name: Upload artifact
        # Automatically uploads an artifact from the './_site' directory by default
        uses: actions/upload-pages-artifact@v3
        with:
          path: "docs/_site/"

  # Deployment job
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4


================================================
FILE: .github/workflows/submit-deps.yml
================================================
# Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive

name: Submit Maven Dependencies

on:
  push:
    branches: ["master"]

permissions:
  contents: write

jobs:
  submit-maven-deps:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          java-version: '21'
          distribution: 'temurin'
      - name: Submit Maven dependency graph
        uses: advanced-security/maven-dependency-submission-action@v5


================================================
FILE: .gitignore
================================================
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
target/

# Eclipse stuff
.classpath
.project
.settings/
.metadata/

# VSCode stuff
.vscode/

# Vim swap files
*.swp

# VS code workspace
*.code-workspace

# backup files
*~
.DS_Store

# Formulog stuff
/codegen/
/src/main/resources/codegen/build/

.idea/

# Jekyll
_site/


================================================
FILE: Dockerfile
================================================
# To upload the Docker images to Dockerhub, log into the Docker console, and then run
#
#   docker buildx build --push --platform linux/amd64,linux/arm64 -t aaronbembenek/formulog:X.Y.Z .
#
# (with the appropriate version number substituted for X.Y.Z).

FROM maven:3.8.6-openjdk-11 AS build
WORKDIR /root/formulog/
COPY src src
COPY pom.xml pom.xml 
RUN mvn package -DskipTests

FROM ubuntu:23.04
ARG version=0.8.0-SNAPSHOT
WORKDIR /root/
RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive \
  apt-get install -y \
  openjdk-11-jre \
  z3 \
  libboost1.81-all-dev \
  libtbb-dev \
  bison \
  build-essential \
  clang \
  cmake \
  doxygen \
  flex \
  g++ \
  git \
  libffi-dev \
  libncurses5-dev \
  libsqlite3-dev \
  make \
  mcpp \
  python3 \
  sqlite3 \
  zlib1g-dev \
  # Install modified Souffle
  && git clone --branch eager-eval https://github.com/aaronbembenek/souffle.git \
  && cd souffle \
  && cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DSOUFFLE_ENABLE_TESTING=OFF \
  && cmake --build build -j$(nproc) \
  && cmake --build build --target install \
  && cmake --build build --target clean
WORKDIR /root/formulog/
COPY --from=build /root/formulog/target/formulog-${version}-jar-with-dependencies.jar formulog.jar
COPY examples examples


================================================
FILE: LICENSE.txt
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
# Formulog

![Build Status](https://github.com/HarvardPL/formulog/actions/workflows/maven.yml/badge.svg)

**TL;DR: write SMT-based program analyses (symbolic executors, refinement type checkers, etc.) in an optimized Datalog-like language.**

Datalog has proven to be a useful language for implementing a range of program analyses, but analyses that use SMT solving cannot be easily written in traditional versions of Datalog.
Formulog sets out to fill this gap by augmenting Datalog with ways to construct and reason about SMT formulas, as well as some first-order functional programming to make life easier.

**Why write your SMT-based analysis in Formulog?**

1. By combining logic programming, functional programming, and SMT solving, Formulog makes it possible to encode many analyses declaratively at the level of mathematical specification (e.g., inference rules), closing the gap between specification and implementation---and often revealing bugs in the spec!
2. This high-level encoding makes it possible for Formulog to apply high-level optimizations to your analysis, like automatic parallelization and goal-directed evaluation.
3. Thanks to our [Formulog-to-Soufflé compiler](https://harvardpl.github.io/formulog/eval_modes/compile.html), you can automatically generate a C++ version of the analysis that leverages highly optimized Datalog algorithms and data structures.

**Interested?**
For more information, check out the [Formulog docs](https://harvardpl.github.io/formulog/) (also available in the [docs](./docs/) directory), including [tips on getting started](https://harvardpl.github.io/formulog/starting.html) and the [language reference](https://harvardpl.github.io/formulog/lang_ref/).
To get a sense for what's involved in building a nontrivial SMT-based analysis in Formulog,
check out our [tutorial](https://harvardpl.github.io/formulog/tutorial/) on implementing a refinement type checker in Formulog.

## Contributing

Contributions to this project are most welcome!
Please open a [GitHub issue](https://github.com/HarvardPL/formulog/issues/new) and then link a pull request to it.
Pull requests must be in the [Google Java format](https://github.com/google/google-java-format) before being merged.
To reformat your code, run `mvn spotless:apply`; you can also check if your code is conformant (without reformatting it) by running `mvn spotless:check`.

## Licensing and Third-Party Libraries

Formulog is released under an [Apache 2.0 license](./LICENSE.txt).

This project uses third-party libraries. You can generate a list of these
libraries and download their associated licenses with this command:

```
mvn license:download-licenses
```

The generated content can be found in the `target/generated-resources/`
directory.


================================================
FILE: changelog.md
================================================
# Changelog

All notable changes to this project will be documented in this file.

## [0.8.0] - 2024-10-18

### Added

- Support for eager evaluation in both interpreter (`--eager-eval` option) and compiler.
- Reorganized documentation and added a lot of new material, including a tutorial.
- Apply Google Java format with Maven.
- Various improvements to the code generator.

### Changed

- Better error reporting for type arity mismatch.
- Clean up CI.
- Better, more consistent CLI options for interpreter and generated code.

### Fixed

- Lexing of arithmetic expressions without spaces.
- Various (rare) interpreter bugs.
- Various bugs in the C++ runtime and generated code.

## [0.7.0] - 2023-02-14

### Added

- Support for compilation to Souffle/C++ (`--codegen` option).

### Changed

- Removed built-in functions `substitute` and `is_free`.

## [0.6.0] - 2022-08-31

### Added

- Support for `bv_to_int`, `int_to_bv`, `bv_extract`, and `bv_concat` formula
  constructors.
- More string manipulation and inspection functions (`substring`,
  `string_length`, `char_at`, `string_to_list`, `list_to_string`,
  `string_to_i32`, and `string_to_i64`).
- Allow argument annotations in relation declarations.
- Option to output relations to disk (`@disk` annotation).
- Explicit annotation `@edb` for EDB relations.

### Changed

- New and improved command line interface.
- New syntax for relation declarations (`rel` instead of `input` and `output`).
- Removed `@external` annotation (replaced by `@disk`).

### Fixed

- Incorrect (non-`smt`) types for formula constructors.
- Various lacunae in documentation.
- Various bugs (including some type checking bugs).

## [0.5.0] - 2020-11-15

### Added

- Give line numbers with parse exceptions.

### Changed

- Signature of `get_model` (takes a list of propositions now)

### Fixed

- Bug in the naive (call-reset) SMT solver strategy.
- Bug in `let fun` expressions.

## [0.4.0] - 2020-09-22

### Added

- Eager semi-naive evaluation algorithm.
- SMT manager that uses push and pop.
- Naive SMT manager that does not do any form of caching.
- Optimal index selection.
- Ability to interface with different solvers and set logic.

### Changed

- Accept .tsv fact files instead of .csv files.
- Allow ML variables to be lowercase.
- The `debugSmt` option logs SMT calls to separate files by solver, instead of
  printing them to same stream.
- Removed `is_valid_opt` and changed signature of `is_sat_opt` to take a list
  of `bool smt` terms.

### Fixed

- Concurrency bug in the memoization of parameterized constructor symbols.
- Bug in the recording of rule evaluation diagnostics.
- Bug in the "freshening" of `let fun` expressions.

## [0.3.0] - 2020-02-03

### Added

- Support for `fold` terms.
- Options to restrict which results are printed after evaluation.
- Nested, variable-capturing functions (i.e., `let fun` expressions).
- Added generic serialization function `to_string`.
- Preliminary (and undocumented) option to compile Formulog program to C++
  instead of interpreting it.

### Changed

- Do not require parentheses around tuple types.
- Do not reorder literals in rules (in order to preserve soundness of
  flow-sensitive type checking).
- Changed the names of some string-related built-in functions (`strcat` is now
  `string_concat` and `strcmp` is now `string_cmp`).
- Removed built-in function `string_of_i32`.

### Fixed

- Made Antlr parser faster by simplifying grammar.
- Changed precedence of infix cons operator (i.e., `::`).
- Added parameterized constructor symbols to fix type soundness issues arising
  from the non-determinate type signatures of some formula constructors.
- Made type checking flow-sensitive to soundly handle destruction of
  user-defined constructors in formulas.

## [0.2.0] - 2019-11-25

### Added

- Support wild card term `??` when "invoking" predicates as functions.
- Constant array constructor `array_const` (from Z3's theory of arrays).
- Ability to do partial magic set rewriting with annotations `@bottomup` and
  `@topdown`.
- Demand transformation simplification for magic set rewriting (following Tekle
  and Liu [2010]).
- Support for record types.
- Support external input facts via annotation `@external`.
- Support sequential runtime (for debugging) via `sequential` system property.
- Support existential anonymous variables in negated atoms.

### Changed

- Increased the amount of information printed with the `debugMst` option.
- Allow ML-style expressions to occur as logic programming terms.
- Prefix names of automatically-generated ADT testers and getters with `#`.
- Removed syntax highlighting for solver variables.
- Don't require periods after declarations and function definitions.
- Print thread name during SMT debugging.
- Make sure that the same SMT call is never made twice (with the same timeout).

### Fixed

- Fixed bug with applying type substitutions that contain mappings to (possibly
  nested) type variables.
- Updated name of formula type in Vim syntax file.
- Fixed a couple bugs in SMT-LIB parser.
- Fixed bug with missing case in unification algorithm.
- Boolean operators now short circuit.
- Reject programs that use top-down rewriting in combination with IDB predicates
  in the ML fragment.
- Make sure that EDB relations are maintained during top-down rewriting, even
  when they are only referenced in the ML fragment.

## [0.1.0] - 2019-04-21

### Added

- Everything (initial release).


================================================
FILE: docs/Gemfile
================================================
source 'https://rubygems.org'

gem "jekyll", "~> 4.3.4" # installed by `gem jekyll`
# gem "webrick"        # required when using Ruby >= 3 and Jekyll <= 4.2.2

gem "just-the-docs", "0.10.0" # pinned to the current release
# gem "just-the-docs"        # always download the latest release


================================================
FILE: docs/_config.yml
================================================
title: Formulog 
description: Datalog for SMT-based static analysis 
theme: just-the-docs

url: https://just-the-docs.github.io

aux_links:
  GitHub Repository: https://github.com/HarvardPL/formulog


================================================
FILE: docs/eval_modes/compile.md
================================================
---
title: Compilation
layout: page
parent: Evaluation Modes
nav_order: 3
---

# Compilation

As an alternative to being directly interpreted (the default), Formulog programs can be compiled into a mix of C++ and Souffle code, which can then in turn be compiled into an efficient executable.
To enable compilation, set the `--codegen` (`-c`) flag; generated code will be placed in the directory `./codegen/` (you can change this using the `--codegen-dir` option).
Within this directory you can use `cmake` to compile the generated code into a binary named `flg`.

For example, to compile and execute the `greeting.flg` program from above, you can use these steps:

```
java -jar formulog.jar -c examples/greeting.flg && \
  cd codegen && \
  cmake -B build -S . -DCMAKE_BUILD_TYPE=Release && \
  cmake --build build -j && \
  ./build/flg --dump-idb
```

This should produce output like the following:

```
Parsing...
Finished parsing (0.000s)
Evaluating...
Finished evaluating (0.029s)

==================== SELECTED IDB RELATIONS ====================

---------- greeting (3) ----------
greeting("Hello, Bob")
greeting("Hello, World")
greeting("Hello, Alice")
```

Use the command `./build/flg -h` see options available when running the executable.

For more information about the Formulog compiler, see the OOPSLA'24 paper [Making Formulog Fast: An Argument for Unconventional Datalog Evaluation](https://dl.acm.org/doi/10.1145/3689754) by Aaron Bembenek, Michael Greenberg, and Stephen Chong.

## Dependencies

To build the generated code, you must have:

- A C++ compiler that supports the C++17 standard (and OpenMP, if you want to produce a parallelized binary)
- `cmake` (v3.21+)
- [`boost`](https://www.boost.org/) (a version compatible with v1.81)
- [`oneTBB`](https://oneapi-src.github.io/oneTBB/) (v2021.8.0 is known to work)
- [`souffle`](https://souffle-lang.github.io/) (v2.3 is known to work; you have to use our [custom fork](https://github.com/aaronbembenek/souffle) if you want to combine compilation with [eager evaluation]({{ site.base_url }}{% link eval_modes/eager.md %}).)

The Formulog Docker image already has these dependencies installed.

================================================
FILE: docs/eval_modes/eager.md
================================================
---
title: Eager Evaluation
layout: page
parent: Evaluation Modes
nav_order: 4
---

# Eager Evaluation

In addition to traditional semi-naive Datalog evaluation, Formulog supports _eager evaluation_, a novel concurrent evaluation algorithm for Datalog that is faster than semi-naive evaluation on some Formulog workloads (often because it induces a more favorable distribution of the SMT workload across SMT solvers).
Whereas semi-naive evaluation batches derived tuples to process them in explicit rounds, eager evaluation eagerly pursues the consequences of each tuple as it is derived.

Using eager evaluation with the Formulog interpreter is easy: just add the `--eager-eval` flag.
Eager evaluation can also be used with the Formulog compiler, provided you install [our custom version of Souffle](https://github.com/aaronbembenek/souffle).
When you configure `cmake` on the generated code, you need to add `-DFLG_EAGER_EVAL=On`.
For example, to build a version of the greeting program that uses eager evaluation, use these commands:

```
java -jar formulog.jar -c examples/greeting.flg && \
  cd codegen && \
  cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DFLG_EAGER_EVAL=On && \
  cmake --build build -j && \
  ./build/flg --dump-idb
```

For more information about eager evaluation, see the OOPSLA'24 paper [Making Formulog Fast: An Argument for Unconventional Datalog Evaluation](https://dl.acm.org/doi/10.1145/3689754) by Aaron Bembenek, Michael Greenberg, and Stephen Chong.

================================================
FILE: docs/eval_modes/index.md
================================================
---
title: Evaluation Modes
layout: page
nav_order: 4
---

# Evaluation Modes

Given a Formulog program, there are many different ways to evaluate it.
These pages describe the primary options supported by our current implementation of Formulog.

================================================
FILE: docs/eval_modes/options.md
================================================
---
title: Options and System Properties 
layout: page
parent: Evaluation Modes
nav_order: 1
---

# Options and System Properties 

Formulog evaluation is controlled by options and system properties.
For example, to interpret the test program with SMT logging and 2
threads, use the `debugSmt` property and `-j 2` option:

```
java -DdebugSmt -jar formulog.jar example/greeting.flg -j 2
```

## Options

Run Formulog with the `-h` flag to see a list of the command-line options that are currently available.
As of Formulog v0.8.0, they are:

```
Usage: formulog [-chV] [--dump-all] [--dump-idb] [--dump-query] [--dump-sizes]
                [--eager-eval] [--smt-stats] [--codegen-dir=<codegenDir>]
                [-D=<outDir>] [-j=<parallelism>]
                [--smt-solver-mode=<smtStrategy>]
                [--dump=<relationsToPrint>]... [-F=<factDirs>]... <file>
Runs Formulog.
      <file>         Formulog program file.
  -c, --codegen      Compile the Formulog program.
      --codegen-dir=<codegenDir>
                     Directory for generated code (default: './codegen').
  -D, --output-dir=<outDir>
                     Directory for .tsv output files (default: '.').
      --dump=<relationsToPrint>
                     Print selected relations.
      --dump-all     Print all relations.
      --dump-idb     Print all IDB relations.
      --dump-query   Print query result.
      --dump-sizes   Print relation sizes.
      --eager-eval   Use eager evaluation (instead of traditional semi-naive
                       Datalog evaluation)
  -F, --fact-dir=<factDirs>
                     Directory to look for fact .tsv files (default: '.').
  -h, --help         Show this help message and exit.
  -j, --parallelism=<parallelism>
                     Number of threads to use.
      --smt-solver-mode=<smtStrategy>
                     Strategy to use when interacting with external SMT solvers
                       ('naive', 'push-pop', or 'check-sat-assuming').
      --smt-stats    Report basic statistics related to SMT solver usage.
  -V, --version      Print version information and exit.
```

**Note:** Formulog does not print any results by default; use one of the
`--dump*` options to print results to the console, or annotate intensional
database (IDB) relations with `@disk` to dump them to disk.

## System Properties

In addition to options, there are many system properties that can be set using
the `-D` flag (as in `-DdebugSmt` or `-DuseDemandTransformation=false`). Some of
the most useful ones are:

* `debugSmt` - log debugging information related to SMT calls to
  the `solver_logs/` directory (defaults to false)
* `debugMst` - print debugging information related to the magic set
  transformation (defaults to false)
* `debugRounds` - print statistics for each round of seminaive evaluation
  (defaults to false)
* `useDemandTransformation` - apply the demand transformation as a
  post-processing step after the magic set transformation (defaults to true)
* `softExceptions` - ignore exceptions during evaluation (i.e., treat them as
  unification failures, and not as something that should stop evaluation;
  defaults to false)
* `sequential` - run interpreter without a thread pool (helpful for debugging
  runtime; defaults to false)
* `printRelSizes` - print final relation sizes (defaults to false)
* `printFinalRules` - print the final, transformed rules (defaults to false)
* `trackedRelations=REL_1,...,REL_n` - print facts from listed relations as they
  are derived (defaults to the empty list)
* `smtLogic=LOGIC` - set the logic used by the external SMT solver (defaults to
  `ALL`)
* `smtSolver=SOLVER` - set the external SMT solver to use; current options are
  `z3` (default), `cvc4`, `yices`, and `boolector`
* `smtDeclareAdts` - whether to declare Formulog algebraic data types to the SMT
  solver upon initialization; set this to false for logics that do not support
  ADTs (defaults to true)

### Alternative SMT Solvers

While we have primarily used Formulog with Z3 as the backend solver, we also
have some experimental (not recently tested) support for other solvers; not all
these solvers handle the full range of Formulog features. To use a solver
besides Z3, you need to set the `smtSolver` system property (see above).  For
each solver, the relevant binary needs to be on your path: `z3` for Z3,
`boolector` for Boolector, `cvc4` for CVC4, and `yices-smt2` for Yices.

================================================
FILE: docs/eval_modes/smt.md
================================================
---
title: Solver Modes and Incremental SMT Solving
layout: page
parent: Evaluation Modes
nav_order: 2
---

# Solver Modes and Incremental SMT Solving

The Formulog runtime associates one external SMT solver process per Formulog
worker thread. Each SMT query is a list of conjuncts. If the SMT solver is
invoked via the `is_sat_opt` or `get_model_opt` function, this list is
explicitly given by the programmer; otherwise, if the solver is invoked via the
`is_sat` or `is_valid` function, the Formulog runtime breaks the supplied
proposition into conjuncts.

Formulog supports three strategies for interacting with external SMT solvers;
they can be set using the `--smt-solver-mode` option.  Consider two SMT queries
`x` and `y`, where `x` immediately precedes `y` and both are lists of conjuncts.

- `naive`: reset the solver between queries `x` and `y` (do not use incremental
SMT solving).
- `push-pop`: try to use incremental SMT solving via the `push` and `pop` SMT
commands. This can work well when query `y` extends query `x`; e.g., `y = c ::
x`, where `c` is an additional conjunct; this situation most commonly occurs
when using [eager evaluation]({{ site.base_url }}{% link eval_modes/eager.md %}).
- `check-sat-assuming`: try to use incremental SMT solving via the
`check-sat-assuming` SMT command. This caches conjuncts in the SMT solver in a
way such that they can be enabled or disabled per SMT query, and works well if
there are shared conjuncts between queries `x` and `y`, but query `x` is not
simply an extension of query `y` (e.g., it omits a conjunct in query `y`).

For more info, see the ICLP'20 extended abstract [Datalog-Based Systems Can Use Incremental SMT Solving](https://aaronbembenek.github.io/papers/datalog-incr-smt-iclp2020.pdf)
by Aaron Bembenek, Michael Ballantyne, Michael Greenberg, and Nada Amin.

================================================
FILE: docs/index.md
================================================
---
title: Home
layout: home
nav_order: 1
---

# Welcome to Formulog!

Formulog is a programming language that extends the logic programming language Datalog with SMT solving and first-order functional programming.
Formulog was designed to be a domain-specific language for implementing SMT-based program analyses, like refinement type checking and symbolic execution.
But who knows---maybe it will also have other uses!

Questions? Feedback? Please [raise a GitHub issue](https://github.com/HarvardPL/formulog/issues/new)!

================================================
FILE: docs/lang_ref/goal_directed_eval.md
================================================
---
title: Goal-Directed Evaluation
layout: page
parent: Language Reference
nav_order: 3
---

# Goal-Directed Evaluation

By default, Formulog uses a standard bottom-up, saturating evaluation strategy.
However, you can also trigger a form of goal-directed, top-down execution if you
include a query in your Formulog program. A query is a rule with an empty head
and a single (non-negated) body atom; for example, `:- p(X, "a").` is a query.
Each program can only have a single query.

The Formulog runtime will use the query to rewrite your program using (a variant
of) the magic set transformation technique. The rewritten program simulates
top-down evaluation when it is evaluated bottom-up. The rewriting happens after
type checking, but before program validation (i.e., before the checks described
in the "Program safety" section are run). This means that you are allowed to
write "invalid" Formulog programs, so long as that when they are rewritten, they
pass the validation checks. For example, this program is invalid evaluated
bottom-up, since there are unbound variables (in the head of the rules):

```
rel member(i32, i32 list)
member(X, X :: _Xs).
member(X, _Y :: Xs) :- member(X, Xs).
```

However, when we add the query `:- member(_X, [1, 2, 3]).`, the program is
rewritten to a valid program that can be evaluated bottom-up:

```
input_member_fb(Xs) :- sup_0_0(_0, Xs).
input_member_fb([1, 2, 3]).
member(X, X :: Xs) :- input_member_fb(X :: Xs).
member(X, _0 :: Xs) :- sup_0_0(_0, Xs), member(X, Xs).
sup_0_0(_0, Xs) :- input_member_fb(_0 :: Xs).
```

Our magic set transformation technique guarantees that if the original program
meets the requirements of stratified negation, then the rewritten program will
also be stratified. However, the transformation can turn a program that
terminates into a program that does not terminate. Also, it cannot be used with
predicates that are "invoked" from the functional fragment of Formulog.

## Query Syntax

Queries are in the form `:- A.` where `A` is a positive (non-negated) atom. The
typical rules about variable usage apply (see the "Anonymous variables" section
of the [Program Safety page]({{ site.base_url }}{% link lang_ref/program_safety.md %})). If you want to have a query consisting of
multiple atoms, write a rule defining a new relation and then query that
relation. For example, the hypothetical query `:- A, B.` could be rewritten as
the rule `R :- A, B.` and query `:- R.`. There can be only one query per
program.

## Partial Goal-Directed Evaluation

It is also possible to only use goal-directed evaluation for part of a program.
You can control this by annotating IDB relation declarations with
`@bottomup` and `@topdown`:

```
@bottomup
rel foo(i32, string)

@topdown
rel bar(i32, i32, string)
```

A relation annotated as `@bottomup` will always be evaluated bottom-up (i.e., in
an exhaustive fashion), and a relation annotated as `@topdown` will always be
evaluated top-down (i.e., in a goal-directed fashion). These annotations can be
used whether or not a top-level query is supplied, and there are no restrictions
on how bottom-up and top-down relations can interact with each other (outside of
the normal restriction of stratified negation). Furthermore, not every relation
needs to be annotated. An unannotated relation will be evaluated bottom-up in
the absence of a top-level query, and top-down otherwise.


================================================
FILE: docs/lang_ref/index.md
================================================
---
title: Language Reference
layout: page
nav_order: 5
---

# Language Reference

This set of documents describes the Formulog language (as opposed to its current implementation).
Please raise a [GitHub issue](https://github.com/HarvardPL/formulog/issues/new) if anything is unclear, incomplete, or incorrect :)

For an overview of Formulog and its motivations, we recommend checking out our [publications]({{ site.base_url }}{% link pubs.md %}).

================================================
FILE: docs/lang_ref/lang_basics.md
================================================
---
title: Language Basics
layout: page
parent: Language Reference
nav_order: 1
---

# Language Basics

Formulog is an extension of Datalog designed to support program analyses that
use logical formulas, such as symbolic execution and refinement type checking.

A Formulog program consists of three main components:

* type definitions;
* relation declarations and definitions; and
* function definitions.

## Types

Formulog has a strong, static type system.

### Built-in Types

Formulog has five built-in primitive types:

* booleans (`bool`), i.e., `true` and `false`;
* signed 32-bit integers (`i32` or equivalently `bv[32]`), as in `42`;
* signed 64-bit integers (`i64` or equivalently `bv[64]`), as in `42L`;
* 32-bit floating point numbers (`fp32` or equivalently `fp[8,24]`), as in
  `42.0F`;
* 64-bit floating point numbers (`fp64` or equivalently `fp[11,53]`), as
  in `42.0`
  or `42.0D`; and
* string constants (`string`), as in `"hello"`.

Beyond these primitive types, Formulog provides the following built-in algebraic
data types:

```
type 'a list =
  | nil
  | cons('a, 'a list)

type 'a option =
  | none
  | some('a)

type cmp =
  | cmp_lt
  | cmp_eq
  | cmp_gt
```

It also has built-in types representing logical formulas, but a discussion of
these is delayed until the [section on logical formulas]({{ site.base_url }}{% link lang_ref/logical_formulas.md %}).

#### List Notation

Formulog provides special notation for terms of the `list` type. The `cons`
constructor can be written using the infix notation `::`; i.e., `X :: Y` is
shorthand for `cons(X, Y)`. A list can also be written as a sequence of
comma-separated elements between a pair of square brackets. For example, the
term `[X, Y, Z]` is shorthand for `cons(X, cons(Y, cons(Z, nil)))`. The term
`[]` is `nil`, the empty list.

Both notations can be used in pattern matching (described below).

### User-Defined Types

Formulog allows users to define their own (polymorphic) algebraic data types.
For instance, this defines a list-like type:

```
type 'a my_list =
  | my_nil
  | my_cons('a, 'a my_list)
```

Like types, constructors must begin with a lowercase letter.

Formulog also has support for tuple types, such as the type `i32 * string`, and
users can also define type aliases, such as this one that defines a map to be an
association list:

```
type ('k, 'v) map = ('k * 'v) my_list
```

Mutually recursive types are written using `and`:

```
type foo =
  | foo1
  | foo2(bar)
and bar =
  | bar1(foo)
  | bar2(bar, bar)
```

You can also define records, as here:

```
type 'a linked_list = {
  val  : 'a;
  next : 'a linked_list option;
}
```

Labels must be valid identifiers and cannot be shared across other types. For
each label, Formulog will automatically generate a function with that name that
extracts the relevant value from the record. For example, in the case of
`linked_list`, Formulog will generate:

```
val  : 'a linked_list -> 'a
next : 'a linked_list -> 'a linked_list option
```

Formulog also supports OCaml-style functional record update, as in this example:

```
type point3d = { x : i32; y : i32; z : i32 }
fun foo : i32 =
  let X = { x = 1; y = 2; z = 3 } in
  let Y = { X with x = -1; z = 0 } in
  x(Y) + y(Y) + z(Y)
```

A call `foo` would evaluate to the value `1`.

## Relations

In Formulog, relations are declared using the keyword `rel`, followed by the
name of the relation, and the types of the relation arguments. Relation
arguments can also be given labels (as documentation):

```
rel foo(i32, string)
rel pair(first: i32, second: i32) (* `first` and `second` are labels *)
```

Some relations are defined only in terms of explicitly enumerated facts. This
one relates pairs of nodes and consists of three pairs:

```
type node = string
rel edge(node, node)
edge("a", "b").
edge("b", "c").
edge("c", "b").
```

Relations like this—that consist only of enumerated facts—can be annotated with
the `@edb` annotation, which tells Formulog to treat them as part of the
extensional database (EDB).

```
@edb rel edge(node, node)
```

Formulog assumes that every relation not annotated with `@edb` is an intensional
database (IDB) relation, meaning that it is defined by rules and should be
treated as an output of the program. For instance, this predicate computes
transitive closure over the previously defined `edge` predicate:

```
rel tc(node, node)
tc(X, Y) :- edge(X, Y).
tc(X, Z) :- tc(X, Y), edge(Y, Z).
```

A Formulog rule consists of a list of head atoms (the atoms to the left of the
`:-`) and a list of body atoms (the atoms to the right of the `:-`). An atom is
either a nullary predicate symbol (i.e., a predicate that takes no arguments) or
a n-ary predicate symbol followed by a parenthesized, comma-separated list of
terms. Each term is either

* a primitive like `42`;
* a variable like `X`;
* a constructed term like `some(X :: [2, 3])`;
* a term of the form `t not C`, where `t` is a term and `C` is a constructor
  symbol (this evaluates to `true` if the outermost constructor of `t` is not
  `C`); or
* a function call to a user-defined or built-in function like `i32_to_i64(42)`
  (functions are described in the next section).

Additionally, atoms in the body of a rule can be negated, as in the atom `!tc(X,
"c")`. Restrictions on the use of negation will be described later in this
guide.

Formulog also has two built-in binary predicates, `=` and `!=`:

```
rel ok
ok :- X = "hello", X != "goodbye".
```

The first of these predicate is true when its arguments unify to the same term,
and the second is true when its arguments cannot be unified.

Finally, any Formulog term of type `bool` can be used in place of an atom in the
rule body, as here:

```
rel foo(bool)
output p
p :- foo(X), X.
```

where the rule is translated to

```
p :- foo(X), X = true.
```

### Reading EDB Relations from Disk

It is possible to specify that an EDB relation should be read from an external
file by annotating its declaration with `@disk`, as in

```
@disk @edb foo(i32, i32, string list)

@disk @edb bar(string)
```

The Formulog runtime will look in the directories specified on the command line
for files called`foo.tsv` and `bar.tsv` (defaulting to the current directory).
As suggested by the `.tsv` extension, these files should contain rows of
tab-separated terms, where each row corresponds to one input fact, and each
column corresponds to an argument position.

So, a file `foo.tsv` might look like this

```
42	0	["x"]
24	1	["", " "]
100	-1	[]
```

(note that the terms on a line are separated by tabs, *not* spaces); it would
correspond to the facts

```
foo(42, 0, ["x"]).
foo(24, 1, ["", " "]).
foo(100, -1, []).
```

Similarly, a `bar.tsv` file looking like this

```
"hello"
"goodbye"
"ciao"
"aloha"
```

would correspond to the facts

```
bar("hello").
bar("goodbye").
bar("ciao").
bar("aloha").
```

Every fact directory must have a `.tsv` file for _every_ external input
relation (the file can be empty).

### Writing IDB Relations to Disk

An IDB relation can be annotated with the annotation `@disk`, in which case
Formulog will dump its contents into a `.tsv` file in the directory specified on
the command line (defaulting to the current directory).

For example, the program

```
rel bar(i32, i32)
bar(1, 2).
bar(3, 4).

@disk rel foo(i32, i32)
foo(X, Y) :- bar(X, Y).
```

will result in a file `foo.tsv` with the tab-separated contents:

```
1	2
3	4
```

## Functions

Formulog allows users to define ML-style functions, that can then be invoked
from within Datalog-style rules. These functions can be polymorphic, but cannot
be higher-order. The functions must have explicit type annotations. For example,
here is a function for finding the nth element of a list:

```
fun nth(Xs : 'a list, N : i32) : 'a option =
  match Xs with
  | [] => none
  | X :: Xs =>
    if N < 0 then none
    else if N = 0 then some(X)
    else nth(Xs, N - 1)
  end
```

No special syntax is required for defining recursive functions, although
mutually recursive functions must be defined with `and`, as here:

```
fun neg_abs(X: i32) = if X > 0 then -X else X

fun is_even(X: i32) : bool =
  let X = neg_abs(X) in 
  X = 0 || is_odd(X + 1)
and is_odd(X: i32) : bool =
  let X = neg_abs(X) in
  X != 0 && is_even(X + 1)
```

We support some of the basic ML syntax constructions, like `match` and `let`.
However, you will find Formulog's syntax to be less flexible than most ML
implementations; for example, `some(X)` is okay but `some X` is not.

Despite the fact that we do not support higher-order functions, we do support
nested functions that can locally capture variables and we also support a
special parameterized term `fold`:

```
fold[f] : ['a, 'b list] -> 'a
```

where `f` is the name of a function of type `['a, 'b] -> 'a`. Here's an example
using both nested functions and `fold`:

```
fun rev(Xs: 'a list) : 'a list =
  let fun cons_wrapper(Xs: 'a list, X: 'a) : 'a list = X :: Xs in
  fold[cons_wrapper]([], Xs)
```

Top-level nullary functions (i.e., ones that take no arguments) can be
introduced with the keyword `const` instead of `fun`:

```
const pi : fp64 = 3.14
(* same as `fun pi : fp64 = 3.14` *)
```

### Lifted Relations and Aggregation

Formulog allows any relation (i.e., EDB relations, IDB relations, and the
built-in relations `!=` and `=`) to be lifted to a boolean-returning function.
For instance, we can write code like this:

```
output bar(i32)

fun foo(N:i32) : bool = bar(N + 1)
```

Here, the function `foo(n)` returns `true` whenever the `bar` relation contains
`n + 1`.

Formulog supports aggregation through the wild card term `??`, which can be used
as an argument when "invoking" a relation as a function. For example, given the
relation `p` that relates a `bool` to an `i32`, we have:

* `p(true, 42)` returns a boolean (whether `true` is related to `42`)
* `p(true, ??)` returns a list of `i32` terms (the ones that are related
  to `true`)
* `p(??, 42)` returns a list of `bool` terms (the ones that are related to `42`)
* `p(??, ??)` returns a list of pairs constituting the relation

The use of lifted predicates must be stratified, as described in the "Program
Safety" document.

### Built-in Functions

Finally, Formulog already has a bunch of basic functions built-in (mostly to do
with manipulating primitives):

* functions for basic mathematical operations for types `i32`, `i64`, `fp32`,
  and `fp64`:
    * addition (`*_add`), as in `fp32_add`
    * subtraction (`*_sub`)
    * multiplication (`*_mul`)
    * negation (`*_neg`)
* bit vector operations for types `i32` and `i64`:
    * bitwise and (`*_and`),
    * bitwise or (`*_or`)
    * bitwise exclusive or (`*_xor`), for types `i32` and `i64`;
    * signed division (`*_sdiv`)
    * signed remainder (`*_srem`)
    * unsigned division (`*_udiv`)
    * unsigned remainder (`*_urem`)
    * shift left (`*_shl`)
    * logical shift right (`*_lshr`)
    * arithmetic shift right (`*_ashr`)
* float operations for types `fp32` and `fp64`:
    * equality (`*_eq`; this is floating point equality, as opposed to
      structural equality via the predicate `=`);
    * division (`*_div`)
    * remainder (`*_rem`)
* Comparison operations `*_lt`, `*_le`, `*_gt`, `*_ge` for types `i32`, `i64`,
  `fp32`, and `fp64` (the bit vector ones are implicitly for signed comparison)
* Signed compare (`*_scmp`) and unsigned compare (`*_ucmp`) operators for types
  `i32` and `i64`; these return a term of type `cmp` (described above)
* boolean operators `!`, `&&`, and `||`
* numeric primitive conversion operations, in the form `*_to_*` (e.g.,
  `i32_to_fp64`)
* the operators `string_to_i32` and `string_to_i64`, which convert the string
  representation of an integer to a term of type `i32 option` and `i64 option`,
  respectively. The string should either be a decimal integer preceded
  optionally by `-` or `+`, or a hexadecimal integer preceded by `0x`. The
  operations return `none` if the string is not in the proper format or
  represents an integer of too great magnitude to fit in 32/64 bits.

Standard arithmetic notation can be used for signed `i32` operations. For
example, `38 + 12 / 3` is shorthand for `i32_add(38, i32_sdiv(12, 3))`.

Formulog supplies some `string` manipulation functions:

```
string_concat      : [string, string] -> string
string_cmp         : [string, string] -> cmp
string_matches     : [string, string] -> bool
string_starts_with : [string, string] -> bool
substring          : [string, i32, i32] -> string option
string_length      : [string] -> i32
char_at            : [string] -> i32 option
string_to_list     : [string] -> i32 list
list_to_string     : [i32 list] -> string
to_string          : 'a -> string
```

The function `string_matches` returns `true` when its first argument matches its
second argument, which can be a regular expression. The function
`string_starts_with` returns `true` when its second argument is a prefix of its
first argument. The function `substring(s, i, j)` extracts the substring of `s`
starting at index `i` and ending at index `j - 1`; it returns `none` for
inappropriate `i` or `j`.

The functions `char_at`, `string_to_list`, and `list_to_string` can be used to
treat a string as a list of characters. We represent characters as terms of
type `i32`. We currently do not guarantee any particular behavior if an integer
less than 0 or greater than 255 is used as a character.

Finally, for the purposes of debugging, Formulog supplies a `print` function of
type `'a -> bool`; it always evaluates to `true`.


================================================
FILE: docs/lang_ref/logical_formulas.md
================================================
---
title: Logical Formulas
layout: page
parent: Language Reference
nav_order: 4
---

# Logical Formulas

Formulog provides support for representing and reasoning about logical formulas.

## Example

This example program would produce the facts `ok1`, `ok2`, and `ok3`.

```
rel ok1
ok1 :-
  is_valid(`false ==> true`),
  !is_sat(`true ==> false`).

rel ok2
ok2 :-
  E = `bv_add(#x[bv[32]], 42) #= 0`,
  is_sat(E),
  F = `bv_sge(#x[bv[32]], 0)`,
  is_sat(F),
  !is_sat(`E /\ F`).

type 'a my_list =
  | my_nil
  | my_cons('a, 'a my_list)

rel ok3
ok3 :-
  Xs = #xs[bool my_list],
  Ys = #ys[bool my_list],
  E = `Xs #= my_cons(true, Ys)`,
  is_sat(E),
  F = `#is_my_nil(Xs)`,
  is_sat(F),
  !is_sat(`E /\ F`).
```

## Formula Types

For every non-formula type τ, there are two corresponding types that are used to
represent τ-valued logical formulas. The first is `τ smt`, which represents a
τ-valued formula. The second is `τ sym`, which represents a τ-valued formula
variable (it is sometimes helpful to distinguish between these two types).

You will often see formulas quoted with backticks, as in

```
`#x[bool] #= true`
```

Quoted terms are type checked differently than terms outside of quotations.
Outside of quotations, the types τ, `τ smt`, and `τ sym` are treated as being
distinct. However, in quoted terms, they are treated as being all the same type.
This bimodal type checking makes it easy to write expressive formulas, while
making sure that evaluation outside of formulas does not get stuck, which might
happen if a boolean formula were passed to a function expecting a concrete
boolean argument.

The Formulog type sensitive is flow-sensitive, in that the order of the atoms
and terms in a rule affect whether that rule is considered well typed or not.
For example, it rejects the first rule in this program and not the second, even
though they are logically equivalent:

```
rel p(bool smt)
rel q(bool)
rel not_ok
rel ok

not_ok :- p(`X`), q(X).
ok     :- q(X), p(`X`).
```

It rejects the first rule because, given a left-to-right reading of the rule,
`X` is bound in a position that has type `bool smt`, and so there is no
guarantee it is a concrete `bool` (which would be required for it to be a member
of `q`). The second rule is fine since `X` is bound in a position that has type
`bool`, which becomes a `bool smt` when it is quoted as an argument to `p`. The
type checker currently uses the order that the rule was originally written; in
the future, the type checker could try to reorder rules to make them well typed.

### Uninterpreted Sorts

Formulog allows users to define uninterpreted sorts that can be used within
formulas. For instance, you can declare a polymorphic uninterpreted sort like
this:

```
uninterpreted sort ('a, 'b) foo
```

## Representing Formulas

Formulas are constructed from a library of constructors and are typically quoted
by backticks, which tells the type checker to use the "formula mode" of the
bimodal type system. Function calls that take arguments cannot appear within
quotations.

### Formula variables

Formulog distinguishes between logic programming variables (like `X`) and
formula variables (like `#x[bool]`). The latter are only interpreted as
variables within formula; otherwise they are ground terms. Formula variables can
be created using a special syntax: a pound sign, followed by a term `t`
of arbitrary type within curly braces, followed by a type τ within square
brackets, as in

```
#{t}[τ]
```

τ cannot have any type variables and cannot contain any formula types (like
`sym` or `smt`). The term `t` is the "name" of the formula variable.

A formula variable will unify with another formula variable only if they have
the same "name" and type. For example,

```
#{42}[bool] = #{"hello"}[bool]
```

never holds, although the formula

```
`#{42}[bool] #= #{"hello"}[bool]`
```

is satisfiable (where `#=` is the notation for formula equality). **Note:** A
formula variable `#{t}[τ]` is guaranteed to not unify with any subterm of `t`;
that is, it is fresh for `t`.

There is also a shorthand syntax: a pound sign, followed by an identifier,
followed by a type within square brackets, as in `#x[bool]`. This is the same
thing as `#{"x"}[bool]`.

### Built-in Formula Terms

Formulog provides built-in terms that are used to construct formulas that should
be interpreted under a particular theory. For the most part, these constructors
directly reflect the SMT-LIB standard.

#### Parameterized Terms

You will see that many formula terms are parameterized with a type or natural
number. For example, the constructor for formula equality, `smt_eq[τ]`, is
parameterized with the type τ of the operands of the equality, and the
constructor for a bit vector constant, `bv_const[k]`, is parameterized with the
width `k` of the bit vector. These parameters are necessary either because the
type information is important to have at runtime (when serializing formulas into
SMT-LIB), or for type safety reasons (issues arise if the type of the term does
not uniquely determine the types of its arguments). However, Formulog can often
infer the correct type without an explicit annotation. If you leave out the
square brackets, Formulog will try to infer every parameter for that term;
alternatively, select parameters can be inferred by using the wildcard parameter
`?`. For example, these formulas all say the same thing:

```
`smt_eq[bv[32]](bv_const[32](42), 0)`
`smt_eq[?](bv_const[?](42), 0)`
`smt_eq(bv_const(42), 0)`
```

Formulog can infer that this is a comparison of 32-bit bit vectors from the fact
that the second operand is the constant `0`, which has type `bv[32]`. However,
the following formulas are unacceptable, since Formulog cannot infer the widths
of the bit vectors in the comparisons:

```
`smt_eq[?](bv_const[?](42), bv_const[?](0))`
`smt_eq(bv_const(42), bv_const(0))`
```

In this case, one annotation is enough to clarify things:

```
`smt_eq[bv[32]](bv_const(42), bv_const(0))`
`smt_eq(bv_const[32](42), bv_const(0))`
```

The parameters to a parameterized constructor have to be fully resolved at
compile time.

#### Logical Connectives

Formulog has the standard first-order logic connectives:

```
smt_not    : bool smt -> bool smt
smt_eq[τ]  : [τ smt, τ smt] -> bool smt
smt_and    : [bool smt, bool smt] -> bool smt
smt_or     : [bool smt, bool smt] -> bool smt
smt_imp    : [bool smt, bool smt] -> bool smt
smt_ite    : [bool smt, 'a smt, 'a smt] -> 'a smt
smt_let[τ] : [τ sym, τ smt, 'a smt] -> 'a smt
smt_exists : [smt_wrapped_var list, bool smt, smt_pattern list list] -> bool smt
smt_forall : [smt_wrapped_var list, bool smt, smt_pattern list list] -> bool smt
```

The quantifiers deserve some explanation. The first argument is a list of
"wrapped" formula variables bound by the quantifier; the type `smt_wrapped_var`
has a single constructor:

```
smt_wrap_var[τ] : τ sym -> smt_wrapped_var
```

The second argument is the body of the quantifier. The third and final argument
represents a list of patterns to supply for trigger-based quantifier
instantiation. Each member of the outermost list represents a single pattern,
possibly consisting of multiple terms. The type `smt_pattern` has a single
constructor:

```
smt_pat[τ] : τ -> smt_pattern
```

However, it is unlikely that you will have to use these constructors directly,
as we supply notation that should cover most situations:

```
~ ...                     (* negation *) 
... #= ...                (* equality *)
... /\ ...                (* conjunction *) 
... \/ ...                (* disjunction *)
... ==> ...               (* implication *)
... <==> ...              (* iff *)
#if ... then ... else ...
#let ... = ... in ... 
```

The binary operators are listed above in order of precedence (so `#=`
binds the most tightly, and `<==>` the least tightly). They all associate to the
right, except for `#=`, which associates to the left.

There is also notation for the quantifiers `forall` and `exists`, as in this
example:

```
  `forall #x[bool]. exists #y[bool]. #x[bool] #= ~#y[bool]`
```

The notation supports binding multiple variables:

```
  `exists #x[bool], #y[bool]. #x[bool] #= ~#y[bool]`
```

You can also specify patterns for trigger-based instantiation. For example, say
that `f` is an uninterpreted function from bools to bools. This formula says
that `f(x) = x` for all `x`, using `f(x)` as a trigger:

```
  `forall #x[bool] : f(#x[bool]). f(#x[bool]) #= #x[bool]`
```

The notation supports patterns with multiple terms (they should be separated by
commas); however, it does not support multiple patterns, in which case you need
to use the explicit constructor described above.

#### Bit Vectors

We have bit vectors, where `bv[k] smt` is a `k`-bit symbolic bit vector:

```
bv_const[k]            : bv[32] -> bv[k] smt
bv_big_const[k]        : bv[64] -> bv[k] smt
bv_neg                 : bv[k] smt -> bv[k] smt
bv_add                 : [bv[k] smt, bv[k] smt] -> bv[k] smt
bv_sub                 : [bv[k] smt, bv[k] smt] -> bv[k] smt
bv_mul                 : [bv[k] smt, bv[k] smt] -> bv[k] smt
bv_sdiv                : [bv[k] smt, bv[k] smt] -> bv[k] smt
bv_srem                : [bv[k] smt, bv[k] smt] -> bv[k] smt
bv_and                 : [bv[k] smt, bv[k] smt] -> bv[k] smt
bv_or                  : [bv[k] smt, bv[k] smt] -> bv[k] smt
bv_xor                 : [bv[k] smt, bv[k] smt] -> bv[k] smt
bv_to_bv_signed[j,k]   : bv[j] smt -> bv[k] smt
bv_to_bv_unsigned[j,k] : bv[j] smt -> bv[k] smt
fp_to_sbv[i,j,k]       : fp[i,j] smt -> bv[k] smt
fp_to_ubv[i,j,k]       : fp[i,j] smt -> bv[k] smt
bv_slt[k]              : [bv[k] smt, bv[k] smt] -> bool smt
bv_sle[k]              : [bv[k] smt, bv[k] smt] -> bool smt
bv_sgt[k]              : [bv[k] smt, bv[k] smt] -> bool smt
bv_sge[k]              : [bv[k] smt, bv[k] smt] -> bool smt
bv_ult[k]              : [bv[k] smt, bv[k] smt] -> bool smt
bv_ule[k]              : [bv[k] smt, bv[k] smt] -> bool smt
bv_ugt[k]              : [bv[k] smt, bv[k] smt] -> bool smt
bv_uge[k]              : [bv[k] smt, bv[k] smt] -> bool smt
bv_extract[j,k]        : [bv[j] smt, i32, i32] -> bv[k] smt
bv_concat[i,j,k]       : [bv[i] smt, bv[j] smt] -> bv[k] smt
```

Note that in some cases the bit vector width is a parameter to the constructor;
as noted previously, parameters can often be inferred.

The `bv_extract` and `bv_concat` constructors currently do not enforce some
constraints on their parameters (for example, with `bv_concat[i,j,k]`, it must
be that `i + j = k`). Illegal parameter choices are therefore not caught by the
type system, and might lead to SMT solver crashes at runtime.

#### Floating Point

And we have floating point, where `fp[j,k] smt` is a symbolic floating point
number with exponent length `j` and signficand length `k`:

```
fp_const[j,k]     : fp[32] -> fp[j,k] smt
fp_big_const[j,k] : fp[64] -> fp[j,k] smt
fp_neg            : fp[j,k] smt -> fp[j,k] smt
fp_add            : [fp[j,k] smt, fp[j,k] smt] -> fp[j,k] smt
fp_sub            : [fp[j,k] smt, fp[j,k] smt] -> fp[j,k] smt
fp_mul            : [fp[j,k] smt, fp[j,k] smt] -> fp[j,k] smt
fp_div            : [fp[j,k] smt, fp[j,k] smt] -> fp[j,k] smt
fp_rem            : [fp[j,k] smt, fp[j,k] smt] -> fp[j,k] smt
fp_to_fp[h,i,j,k] : fp[h,i] smt -> fp[j,k] smt
bv_to_fp[i,j,k]   : bv[i] smt -> fp[j, k] smt
fp_lt[j,k]        : [fp[j,k] smt, fp[j,k] smt] -> bool smt
fp_le[j,k]        : [fp[j,k] smt, fp[j,k] smt] -> bool smt
fp_gt[j,k]        : [fp[j,k] smt, fp[j,k] smt] -> bool smt
fp_ge[j,k]        : [fp[j,k] smt, fp[j,k] smt] -> bool smt
fp_is_nan[j,k]    : fp[j,k] smt -> bool smt
fp_eq[j,k]        : [fp[j,k] smt, fp[j,k] smt] -> bool smt
```

To make it syntactically more pleasant to deal with common floating point types,
instead of supplying both the exponent and significand length, users can supply
a single parameter that is expanded into the appropriate exponent and
significand:

* the parameter `16` is expanded to `5,11`;
* the parameter `32` is expanded to `8,24`;
* the parameter `64` is expanded to `11,53`; and
* the parameter `128` is expanded to `15,113`.

For example, the term `fp_const[32](...)` is equivalent to
`fp_const[8,24](...)`.

#### Integers

Mathematical integers are represented by the type `int smt`:

```
int_abs       : int smt -> int smt
int_neg       : int smt -> int smt
int_const     : bv[32] -> int smt
int_big_const : bv[64] -> int smt
int_ge        : [int smt, int smt] -> bool smt
int_gt        : [int smt, int smt] -> bool smt
int_le        : [int smt, int smt] -> bool smt
int_lt        : [int smt, int smt] -> bool smt
int_add       : [int smt, int smt] -> int smt
int_mul       : [int smt, int smt] -> int smt
int_mod       : [int smt, int smt] -> int smt
int_sub       : [int smt, int smt] -> int smt
int_div       : [int smt, int smt] -> int smt
int_to_bv[k]  : int smt -> bv[k] smt
bv_to_int[k]  : bv[k] smt -> int smt
```

Note that `int_to_bv[k]` and `bv_to_int[k]` do not correspond to any operations
in the SMT-LIB standard. These are serialized as `int2bv` and `bv2int`
operations, which are supported by Z3, but not by some other solvers.

#### Arrays

Arrays from `'a` to `'b` are represented by the type `('a, 'b) array smt`:

```
array_select[τ]  : [(τ, 'a) array smt, τ smt] -> 'a smt 
array_store      : [('a, 'b) array smt, 'a smt, 'b smt] -> ('a, 'b) array smt
array_default[τ] : (τ, 'a) array smt -> 'a smt
array_const      : 'b smt -> ('a, 'b) array smt
```

#### Strings

Symbolic strings are represented by the type `string smt`:

```
str_at       : string smt, int smt -> string smt
str_concat   : string smt, string smt -> string smt
str_contains : string smt, string smt -> bool smt
str_indexof  : string smt, string smt, int smt -> int smt
str_len      : string smt -> int smt
str_prefixof : string smt, string smt -> bool smt
str_replace  : string smt, string smt, string smt -> string smt
str_substr   : string smt, int smt, int smt -> string smt
str_suffixof : string smt, string smt -> bool smt
```

These operations follow the theory of strings supported by Z3 and CVC4.

### Using Algebraic Data Types and Records in Formulas

Terms constructed from user-defined algebraic data types can also be used in
formulas, where they are interpreted under the theory of algebraic data types.
Say we define this type:

```
type 'a my_list =
  | my_nil
  | my_cons('a, 'a my_list)
```

In addition to being able to use the constructors `my_nil` and `my_cons` within
a formula, one can also use constructors that are automatically generated by
Formulog and that make it easier to state formulas about `my_list` terms:

```
#is_my_nil  : 'a my_list smt -> bool smt
#is_my_cons : 'a my_list smt -> bool smt
#my_cons_1  : 'a my_list smt -> 'a smt
#my_cons_2  : 'a my_list smt -> 'a my_list smt
```

These automatically generated constructors fall into two categories: testers,
which are identified by the prefix `#is_` followed by the name of the
constructor and are used to test the outermost constructor of a (possibly
symbolic) term, and getters, which are identified by the name of the constructor
prefixed with a `#` and followed by an underscore and an argument position, and
which are used to extract the argument of a (possibly symbolic)
term.

Symbolic getters are also created for records, where each getter is the name of
the relevant label prefixed with `#`.

### Uninterpreted Functions

Formulog also provides a way to declare uninterpreted functions, as here:

```
uninterpreted fun foo(bv[32] smt) : bool smt
```

This effectively defines a new constructor for `bool smt` that expects a single
argument of type `bv[32] smt`. Uninterpreted functions can only be used within
formulas.

## Reasoning about Formulas

Formulog currently provides these functions for reasoning about/manipulating
formulas:

```
is_sat       : bool smt -> bool
is_sat_opt   : [bool smt list, i32 option] -> bool option
is_valid     : bool smt -> bool
get_model    : [bool smt list, i32 option] -> model option
query_model  : ['a sym, model] -> 'a option
```

The functions `is_sat` and `is_valid` check the satisfiability and validity,
resp., of their argument and throw an exception if the SMT solver returns
`unknown`. The function `is_sat_opt` takes a list of propositions and checks for
the satisfiability of their conjunction, returning `none` in the case of
`unknown`; it also takes an argument for an optional timeout.

The function `get_model` takes a list of propositions and an optional timeout
and returns a model for the conjunction of those propositions if the SMT solver
finds one in time; it returns `none` otherwise. Variables in a model can be
inspected using `query_model`, which will return
`none` if a variable is not present in the model or if it is of a type that
cannot be concretely represented in Formulog (for example, Formulog does not
have a concrete representation of a 13-bit vector).


================================================
FILE: docs/lang_ref/program_safety.md
================================================
---
title: Program Safety
layout: page
parent: Language Reference
nav_order: 2
---

# Program Safety

Formulog imposes some restrictions on programs so that it can give guarantees
about runtime behavior. Beyond the type system, these restrictions fall into
two categories: restrictions on variable usage and restrictions on negation.

## Variable Usage

Correct variable usage is a tricky aspect of logic programming; this section
describes Formulog's restrictions on this front.

### Anonymous Variables

To help catch bugs related to variable usage, Formulog requires that every
variable that does not start with an underscore occurs more than once in its
scope. Every variable that begins with an underscore is treated as "anonymous,"
in that every occurrence of that variable represents a distinct variable. For
this reason, Formulog does not allow any variable that begins with an underscore
to occur more than once in a scope, except for the traditional anonymous
variable `_`.

### Binding Variables

Formulog requires that every variable in a rule is "bound." In what follows, we
use the identifiers `p` for a relation, `c` for a constructor, and `f` for a
function. A variable is bound when:

* it is explicitly unified via the `=` built-in predicate with a term that does
  not contain any unbound variables (e.g., `X` and `Y` are bound via the atom
  `(X, 0) = (42, Y)`);
* it is an anonymous variable that occurs as a top-level argument to a negated
  atom (e.g., `_X` is considered bound in `!p(_X)`); or
* it occurs in the argument to a positive atom in the rule body, and that
  occurrence is not also the argument to a function call. For example, the
  occurrence of `X` in the atom `p(c(X))` is bound, but it is not bound in the
  atom `p(f(X))`.
  
Furthemore, the ML fragment of Formulog is evaluated using call-by-value
semantics, which means that the arguments to a function need to be normalized
and ground (i.e., variable-free) before a call site can be evaluated.
Consequently, every variable occurring as an argument to a function must be
bound going into the call site.

To check whether these variable binding conditions are met, the Formulog runtime
currently performs a single pass over the rule, going from left to right across
the rule body, and then finishing on the rule head. This means that the order in
which variables are bound affects whether the Formulog runtime accepts a rule or
not, even though different orders might be logically equivalent. For example,
this rule is disallowed, because the call to `f(X)` occurs syntactically before
the binding of `X` (given a left-to-right reading of the rule):

```
not_ok :- p(f(X)), p(X).
```

This rule would be accepted if it were rewritten as:

```
ok :- p(X), p(f(X)).
```

Similarly, the checker is overly conservative in its treatment of the `=`
predicate, rejecting rules that require "sub-unifications" to occur in an order
that is not left to right:

```
not_ok :- (_, X) = (f(X), 42).
```

Here, the second argument of the tuple needs to be unified before the first
argument can be. An equivalent rule would be accepted:

```
ok :- X = 42, _ = f(X).
```

In theory, Formulog could rewrite rules in situations like these to make it
easier to meet the binding requirements. It currently does not do so because
type checking is flow-sensitive, and so the runtime would need to ensure that
any rewriting results in a rule that is still well-typed. Although we have not
found our current approach to be a hindrance in practice, this is something that
we could implement in the future.

## Negation, Aggregation, and Stratification

To ensure that every program has a least model, Formulog requires the use of
stratified negation and aggregation, a common restriction in Datalog.
Intuitively, this restriction ensures that there are no recursive
negation/aggregation dependencies between predicates.

Since Formulog allows predicate symbols to appear in function bodies,
determining whether a Formulog program is stratified is slightly more
complicated than in the Datalog case. To determine if a program is stratified
we construct a dependence graph, where each node represents a different
predicate. There is a "positive" edge from a predicate `p` to a predicate `q`
if `p` appears in a positive atom in the body of a rule defining `q`. There is
a "negative" edge from `p` to `q` if `p` appears in a negated atom in the body
of a rule defining `q`, or `p` appears in the body of an expression that may be
transitively invoked from a rule defining `q`. A program is stratified if there
are no cycles in the dependence graph that include a "negative" edge.


================================================
FILE: docs/pubs.md
================================================
---
title: Publications and Artifacts
layout: page
nav_order: 6
---

# Publications and Artifacts

Check out our academic papers to learn more about the science behind Formulog.

## Formulog Language Design 

Our [OOPSLA'20 paper](https://dl.acm.org/doi/10.1145/3428209) introduces Formulog, motivates its language design, and demonstrates its use through three extensive case studies.

To cite this paper, please use an entry like this one:

```
@article{Bembenek2020Formulog,
  author  = {Aaron Bembenek and Michael Greenberg and Stephen Chong},
  title   = {Formulog: {D}atalog for {SMT}-{B}ased {S}tatic {A}nalysis},
  journal = {Proceedings of the {ACM} on Programming Languages},
  year    = {2020},
  volume  = {4},
  number  = {OOPSLA},
  doi     = {10.1145/3428209},
  pages   = {141:1--141:31}
}
```

The refereed artifact for this paper is [available on Zenodo](https://zenodo.org/records/4039122). 

## Formulog Performance 

Our [OOPSLA'24 paper](https://dl.acm.org/doi/10.1145/3689754) describes speeding up Formulog via 1) compilation to Soufflé and 2) eager evaluation, a novel Datalog evaluation strategy that works well for some SMT-heavy workloads.

To cite this paper, please use an entry like this one:

```
@article{Bembenek2024Making,
  author  = {Aaron Bembenek and Michael Greenberg and Stephen Chong},
  title   = {Making {F}ormulog {F}ast: An {A}rgument for {U}nconventional {D}atalog {E}valuation},
  journal = {Proceedings of the {ACM} on Programming Languages},
  year    = {2024},
  volume  = {4},
  number  = {OOPSLA2},
  doi     = {10.1145/3689754},
  pages   = {314:1--314:30}
}
```

The refereed artifact for this paper won a [distinguished artifact](https://2024.splashcon.org/track/splash-2024-oopsla-artifacts#distinguished-artifacts) award; it is [available on Zenodo](https://zenodo.org/records/13372573).

## Short Papers

For more information on how Formulog interfaces with external SMT solvers, see the ICLP'20 extended abstract [Datalog-Based Systems Can Use Incremental SMT Solving](https://arxiv.org/html/2009.09158v1/#EPTCS325.7) by Aaron Bembenek, Michael Ballantyne, Michael Greenberg, and Nada Amin ([PDF available here](https://aaronbembenek.github.io/papers/datalog-incr-smt-iclp2020.pdf)).

For an introduction to Formulog geared towards an audience already well versed in Datalog, see the Datalog 2.0'22 short paper [Formulog: Datalog + SMT + FP](https://ceur-ws.org/Vol-3203/short2.pdf) by Aaron Bembenek, Michael Greenberg, and Stephen Chong.

================================================
FILE: docs/starting.md
================================================
---
title: Getting Started
layout: page
nav_order: 2
---

# Getting Started

Thank you for your interest in Formulog!
This page describes how to set up Formulog and provides some pointers on writing Formulog programs.

## Setting up Formulog

There are three main ways to set up Formulog (listed in increasing order of number of dependencies):

- Using the Docker image
- Downloading the JAR
- Building from source

### Use the Docker image

Prebuilt images are available on [Docker Hub](https://hub.docker.com/r/aaronbembenek/formulog/tags).
If you have Docker installed, you can spin up an Ubuntu container with Formulog, our custom version of Soufflé, and some example programs by running this command (replace `X.Y.Z` with the latest version):

```bash
docker run -it aaronbembenek/formulog:X.Y.Z # may require sudo
```

This should place you in the directory `/root/formulog/`, with a file `formulog.jar` and some example Formulog programs in the `examples/` directory.

### Download the JAR

Dependencies:

- JRE 11+
- Z3 (v4.12.2 is known to work; other recent versions should work too)

You can find a prepackaged JAR file in the [Releases section](https://github.com/HarvardPL/formulog/releases) of the GitHub repository.

### Build from Source

Dependencies:

- JDK 11+
- Maven (v3.9.5 is known to work)
- Z3 (v4.12.2 is known to work; other recent versions should work too)

To build an executable JAR, run the command `mvn package` from the project source directory.
This will create an executable JAR with a name like `formulog-X.Y.Z-SNAPSHOT-jar-with-dependencies.jar` in the `target/` directory.

If `mvn package` fails during testing, it might mean that there is a problem connecting with Z3.
You can compile without testing by adding the `-DskipTests` flag.

### Test Your Setup

If you have set up Formulog, you should now have an executable JAR at your fingertips.
The JAR expects a single Formulog file as an argument.
Let's test it on the following Formulog program (available in the Docker image and the base repository directory as `examples/greeting.flg`):

```
@edb rel entity(string)
entity("Alice").
entity("Bob").
entity("World").

rel greeting(string)
greeting(Y) :-
  entity(X),
  some(M) = get_model([`#y[string] #= str_concat("Hello, ", X)`], none),
  some(Y) = query_model(#y[string], M).
```

Run the following command (where `formulog.jar` is replaced with the name of the executable JAR):

```
java -jar formulog.jar examples/greeting.flg --dump-idb
```

You should get results like these, indicating that three `greeting` facts have been derived:

```
Parsing...
Finished parsing (0.202s)
Type checking...
Finished type checking (0.024s)
Rewriting and validating...
Finished rewriting and validating (0.253s)
Evaluating...
Finished evaluating (0.354s)

==================== SELECTED IDB RELATIONS ====================

---------- greeting (3) ----------
greeting("Hello, Alice")
greeting("Hello, Bob")
greeting("Hello, World")
```

## Writing Formulog Programs

Now that you have Formulog set up, the fun part starts: writing Formulog programs!

Check out our [tutorial]({{ site.base_url }}{% link tutorial/index.md %}) for a walk-through of how to encode a refinement type system in Formulog.
Additional short-ish example programs can be found in the `examples/` directory (in the Docker image or repository base directory).
For examples of larger developments, see the case studies we have used in publications:

- [a refinement type checker](https://github.com/aaronbembenek/making-formulog-fast/blob/main/benchmarks/dminor/bench.flg)
- [a bottom-up points-to analysis for Java](https://github.com/aaronbembenek/making-formulog-fast/blob/main/benchmarks/scuba/bench.flg)
- [a symbolic executor an LLVM fragment](https://github.com/aaronbembenek/making-formulog-fast/blob/main/benchmarks/symex/bench.flg)

See the [language reference]({{ site.base_url }}{% link lang_ref/index.md %}) for details about Formulog constructs.

Syntax highlighting is available for Visual Studio Code (follow instructions [here](https://github.com/HarvardPL/formulog-syntax)) and Vim (install [misc/flg.vim](https://github.com/HarvardPL/formulog/blob/master/misc/flg.vim)).

Finally, please raise a [GitHub issue](https://github.com/HarvardPL/formulog/issues/new) if you want to try out Formulog but would like additional information or assistance---we're happy to help! :)


================================================
FILE: docs/tutorial/index.md
================================================
---
title: Tutorial
layout: page
nav_order: 3
---

# Tutorial: Building a Refinement Type Checker

In this tutorial, we'll implement a type checker for a small (but still interesting) refinement type system in Formulog.
In particular, we'll implement the declarative, bidirectional type checking rules for the first system in the article [Refinement Types: A Tutorial](https://arxiv.org/abs/2010.07763v1) by Ranjit Jhala and Niki Vazou [1].
Our hope is that our tutorial gives a good overview of many Formulog features, and a flavor of what it is like to program a nontrivial analysis in Formulog.

### Intended Audience

This tutorial is intended for the PL practitioner (e.g., a grad student, academic, or research engineer).
We assume you are familiar with SMT solving, ML-like functional languages, and logic programming, and also have some level of comfort with formal programming language notation (like inference rules).
It is also probably helpful to have read one of our [Formulog publications]({{ site.base_url }}{% link pubs.md %}), which should (hopefully) give a good sense for the overall design of the language and its motivations.
If you are not familiar with refinement type checking or bidirectional type systems, you should probably skim the first few sections of the tutorial by Jhala and Vazou [1] (we'll focus on Sections 3.1 and 3.2).

### Help Improve This Tutorial

We're eager for feedback on ways to make this tutorial clearer and more useful!
If you have a question about the content of this tutorial, a suggestion for improvement, or a bug report, please let us know by raising a [GitHub issue](https://github.com/HarvardPL/formulog/issues/new).

### Attribution

This tutorial includes figures from the article [Refinement Types: A Tutorial](https://arxiv.org/abs/2010.07763v1) by Ranjit Jhala and Niki Vazou [1], which has been published under a [CC BY 4.0 license](https://creativecommons.org/licenses/by/4.0/).
We will refer to this article as "JV" for short.

## General Approach

One of the advantages of writing a program analysis in Datalog is to be able to implement analysis logic at the level of mathematical specification.
Formulog extends this benefit to analyses where the formal specification involves constructing logical terms (i.e., SMT formulas) and determining their satisfiability/validity (i.e., SMT solving).
Our typical approach when implementing an analysis in Formulog is thus to try to directly translate the formal specification of an analysis---inference rules and mathematical helper functions---into Horn clauses and functional code.

This is the approach we will follow in this tutorial: directly translate the formalism of JV as we encounter it, and then go back to patch our implementation as necessary.
Concretely, we will work our way through JV Sections 3.1 and 3.2.
For the full, final code, see [tutorial.flg](https://github.com/HarvardPL/formulog/blob/master/examples/tutorial.flg).

## Definitions

The first formalism we encounter in JV Section 3.1 is a definition of types and environments (Figure 3.1), which also refers to the definitions of predicates (Figure 2.1).

![Figure 3.1](./images/figure_3_1.png)

![Figure 2.1](./images/figure_2_1.png)

We can encode these BNF-style definitions (along with the definition of constraints) using Formulog's support for algebraic data types:

```
(* An algebraic data type with a single variant *)
type basic_typ =
    | b_int

(* A type alias *)
type var = string

(* Interpreted operations: for simplicity, we'll support just a few *)
type op =
    | o_add
    | o_eq

type pred =
    | p_var(var)
    | p_bool(bool)
    | p_int(i32) (* i32 is the type of a 32-bit signed integer *)
    | p_interp_op(op, pred, pred)
    | p_conj(pred, pred)
    | p_disj(pred, pred)
    | p_neg(pred)
    | p_ite(pred, pred, pred)

type constraint =
    | c_pred(pred)
    | c_conj(constraint, constraint)
    | c_imp(var, basic_type, pred, constraint)

type typ =
    | t_refined(basic_typ, var, pred)
    | t_func(var, typ, typ)

type kind =
    | k_base
    | k_star

(* Tuples and lists are built-ins *)
type env = (var * typ) list
```

We can then similarly encode expressions, following Figure 3.2.

![Figure 3.2](./images/figure_3_2.png)

```
type expr =
    | e_int(i32)
    | e_var(var)
    | e_let(var, expr, expr)
    | e_lambda(var, expr)
    | e_app(expr, var)
    | e_annot(expr, typ)
```

### Well-formedness

The first judgments---which define type well-formedness---are given in Figure 3.3.

![Figure 3.3](./images/figure_3_3.png)

Typically, in Formulog, you would encode inference rules like these using Horn clauses, so let's do that here.

First, we need to declare a relation for well-formedness:

```
rel wf(env, typ, kind)
```

We can then encode the rules one by one, with reference to this relation.
Let's start with the simplest rule, Wf-Kind:

```
wf(G, T, k_star) :- wf(G, T, k_base).
```

Horn clauses are implications (read right to left), so this rule is saying that types that are well-formed at kind base are also well-formed at kind star.
Identifiers beginning with an uppercase letter are logic programming variables, which are implicitly universally quantified across the entire rule.

Wf-Fun is not too bad to encode either:

```
wf(G, t_func(X, S, T), k_star) :-
    wf(G, S, _Ks),
    wf((X, S) :: G, T, _Kt).
```

Two things to note:

- Identifiers that begin with an underscore are anonymous variables. Formulog will reject rules where a non-anonymous variable only appears once (a common bug).
- As in ML variants, the infix constructor `::` is the cons of a value and a list; in this case, we use it to extend the environment with a new binding (represented as a tuple).

Once we get to WF-Base, we notice that we're missing something: the premise requires the well-sortedness of a predicate, a judgment that is not defined by JV, although the authors say that this amounts to standard type checking (with refinements ignored).
We'll have to declare a relation for this and encode the rules:

```
rel pred_wf(env, pred, basic_typ)
```

First, we might try to encode that a boolean value is, well, a boolean; to do so, we need to revise our definition of basic types to also include booleans:

```
(* Revised definition *)
type basic_typ =
    | b_int
    | b_bool
```

We can then encode the rule for boolean literals:

```
pred_wf(_G, p_bool(_B), b_bool).
```

The rules are straightforward for most of the other constructs:

```
pred_wf(_G, p_int(_I), b_int).

pred_wf(G, p_interp_op(o_add, P1, P2), b_int) :-
    pred_wf(G, P1, b_int),
    pred_wf(G, P2, b_int).

pred_wf(G, p_interp_op(o_eq, P1, P2), b_bool) :-
    pred_wf(G, P1, T),
    pred_wf(G, P2, T).

(* We can define a Horn clause with two heads, meaning both conclusions hold *)
pred_wf(G, p_conj(P1, P2), b_bool),
pred_wf(G, p_disj(P1, P2), b_bool) :-
    pred_wf(G, P1, b_bool),
    pred_wf(G, P2, b_bool).

pred_wf(G, p_neg(P), b_bool) :-
    pred_wf(G, P, b_bool).

pred_wf(G, p_ite(P1, P2, P3), T) :-
    pred_wf(G, P1, b_bool),
    pred_wf(G, P2, T),
    pred_wf(G, P3, T).
```

That leaves us just handling variables; to do so, we need to define what it means to look up a variable in an environment.
Formulog's first-order functional programming comes in handy for defining this type of helper function:

```
fun lookup(x: var, g: env): typ option =
    match g with
    | [] => none
    | (y, t) :: rest => if x = y then some(t) else lookup(x, rest)
    end
```

The `option` type (with its constructors `none` and `some`) is built into Formulog.
We can now define the judgment for variables, as well as our final judgment for type well-formedness.

```
pred_wf(G, p_var(V), B) :-
    lookup(V, G) = some(t_refined(B, _, _)).

wf(G, t_refined(B, V, P), k_base) :-
    K = (V, t_refined(B, V, p_true)),
    pred_wf(K :: G, P, b_bool),
```

Note that in the rule defining a case of `pred_wf` we invoke the `lookup` function we defined previously.
Formulog allows ML-style functions to be invoked from within Horn clauses.

### Converting Constraints and Predicates to SMT

The next judgments we encounter in JV are those for entailment and subtyping (Figure 3.4).

![Figure 3.4](./images/figure_3_4.png)

The rule Ent-Emp requires us to determine if a constraint is valid; we can do this in Formulog by using the built-in function `is_valid`, provided that we convert a term of type `constraint` to a term of type `bool smt` (the type in Formulog representing an SMT proposition).
That doesn't sound too bad; we can write a function to do that.
The conjunction case is straightforward:

```
fun constraint2smt(c: constraint): bool smt =
    match c with
    | c_conj(c1, c2) =>
        let s1 = constraint2smt(c1) in
        let s2 = constraint2smt(c2) in
        `s1 /\ s2`
    (* TODO: other cases *)
    end
```

Note that SMT formulas are demarcated by backticks, and `/\` is the built-in notation for SMT conjunction.

Now let's consider another case in the match statement, corresponding to the constructor `c_pred(pred)`.
Here, we need to construct a term of type `bool smt` out of a term of type `pred`.
Let's try to do that in a helper function, `pred2smt`:

```
fun pred2smt(p: pred): bool smt =
    match p with
    (* Putting a term in quotes makes it type at the SMT level *)
    | p_bool(b) => `b`
    | p_conj(p1, p2) =>
        let b1 = pred2smt(p1) in
        let b2 = pred2smt(p2) in
        `b1 /\ b2`
    | p_disj(p1, p2) =>
        let b1 = pred2smt(p1) in
        let b2 = pred2smt(p2) in
        `b1 \/ b2`
    | p_neg(p1) => let b = pred2smt(p1) in `~b`
    | p_interp_op(o_eq, p1, p2) =>
        let b1 = pred2smt(p1) in
        let b2 = pred2smt(p2) in
        `b1 #= b2`
    (* TODO: other cases *)
    end
```

So far, so good.
But how about when we get to the `p_int` case?
The function signature requires us to return a term of type `bool smt`, but that doesn't make any sense in this case.
In fact, if we take a closer look at how predicates are defined, we can see that the syntax for predicates allow bool-valued and int-valued terms to be mixed.
We could go back, and try to redefine the syntax for predicates in a way that distinguishes between bool-valued and int-valued terms.
However, even if this were possible, doing so would have a few downsides:

- it takes us farther away from the formalism of JV;
- it would likely lead to duplication, since we would need, e.g., two different constructors for equality, one where the subterms are ints and one where the subterms are bools; and
- it does not seem like a very flexible approach as our language of predicates becomes more complex.

There is another alternative, which is to push the bool-vs-int distinction into the SMT level, using the SMT theory of algebraic data types (this follows the encoding approach of the Dminor refinement type system [2]).
To do so, we'll define a new algebraic data type, representing a value in a predicate (which will be either an integer or a bool):

```
type val =
    | v_int(int)
    | v_bool(bool)
```

This type will only appear in SMT formulas.
We can then redefine `pred2smt` to return a term of type `val smt`---i.e., a `val`-valued SMT term---instead of a term of type `bool smt`:

```
fun pred2smt(p: pred): val smt =
    match p with
    | p_bool(b) => `v_bool(b)`
    | p_conj(p1, p2) =>
        let v1 = pred2smt(p1) in
        let v2 = pred2smt(p2) in
        `v_bool(#v_bool_1(v1) /\ #v_bool_1(v2))`
    | p_disj(p1, p2) =>
        let v1 = pred2smt(p1) in
        let v2 = pred2smt(p2) in
        `v_bool(#v_bool_1(v1) \/ #v_bool_1(v2))`
    | p_neg(p1) =>
        let v1 = pred2smt(p1) in
        `v_bool(~#v_bool_1(v1))`
    | p_int(n) => `v_int(int_const(n))`
    | p_interp_op(o, p1, p2) =>
        let v1 = pred2smt(p1) in
        let v2 = pred2smt(p2) in
        match o with
        | o_eq => `v_bool(v1 #= v2)`
        | o_add => `v_int(int_add(#v_int_1(v1), #v_int_1(v2)))`
        end
    | p_ite(p1, p2, p3) =>
        let v1 = pred2smt(p1) in
        let v2 = pred2smt(p2) in
        let v3 = pred2smt(p3) in
        `#if #v_bool_1(v1) then v2 else v3`
    | p_var(x) => `#{x}[val]`
    end
```

There's a lot going on here.
Let's look at some simple cases first.

- `` p_bool(b) => `v_bool(b)` ``: We have a term `b` of type `bool`; to turn it into a term of type `val`, we wrap it in the constructor `v_bool`; to turn this into a term of type `val smt`, we quote it with backticks.
- `` p_int(n) => `v_int(int_const(n))` ``: We have a term `n` of type `i32`; we can turn it into a term of type `int smt` (a mathematical integer in SMT land) by wrapping it with the constructor `int_const`, and then supply this term as an argument to the `v_int` constructor to create a term of type `val smt`. Note that even though the `v_int` constructor is defined to take a term of type `int` and not `int smt`, the two types are conflated when occurring within an SMT formula (i.e., between backticks).
- `` p_var(x) => `#{x}[val]` ``: we take a predicate-level variable `x` and construct an SMT-level variable named `x` that is typed as `val` within the SMT formula. Technically, the syntax `#{x}[val]` creates a Formulog term of type `val sym` (i.e., a `val`-valued SMT variable), and the backticks then raise the type to `val smt`.

In the other cases, we see the use of the constructors `#v_int_1` and `#v_bool_1`.
For all datatypes (that can be expressed at the SMT level), Formulog creates constructors of this form that can be used within SMT formulas to access the arguments of constructors.
For example, `#v_int_1` is defined so that `#v_int_1(v_int(n))` is the int `n`, but `#v_int_1(v_bool(_))` is any int.
This approach reflects the SMT-LIB theory of algebraic datatypes.
Essentially, these constructors allow us to coerce (within an SMT formula) a value of type `val` to a `bool` or `int`.

Now that we have `pred2smt`, we can go back and finish our definition of `constraint2smt`:

```
fun constraint2smt(c: constraint): bool smt =
    match c with
    | c_conj(c1, c2) =>
        let s1 = constraint2smt(c1) in
        let s2 = constraint2smt(c2) in
        `s1 /\ s2`
    | c_pred(p) => let s = pred2smt(p) in `#v_bool_1(s)`
    | c_imp(x, _b, p1, c1) =>
        (* Note that we do not actually need to use the basic type `_b` *)
        let prem = pred2smt(p1) in
        let conl = constraint2smt(c1) in
        (* This uses more special syntax for SMT formulas *)
        `forall #{x}[val]. #v_bool_1(prem) ==> conl`
    end
```

### Entailment and Subtyping

Now that we have a way to turn constraints into terms of type `bool smt`, we can start implementing the rules for entailment and subtyping (Figure 3.4, repeated from above).

![Figure 3.4](./images/figure_3_4.png)

First, the rules for entailment:

```
rel ent(env, constraint)

ent([], C) :- is_valid(constraint2smt(C)).

ent((X, t_refined(B, X, P)) :: G, C) :-
    ent(G, c_imp(X, B, P, C)).
```

The function `is_valid` is a built-in that calls out to an external SMT solver.

For the subtyping rules, we need to define helper functions for substituting variables in predicates (described briefly in Section 2.2) and types (explicitly given in Section 3.3.1).

![Section 3.3.1](./images/section_3_3_1.png)

```
fun subst_pred(p: pred, y: var, z: var): pred =
    match p with
    | p_bool(_) | p_int(_) => p
    | p_var(x) => p_var(if x = y then z else x)
    | p_interp_op(o, p1, p2) =>
        let p1 = subst_pred(p1, y, z) in
        let p2 = subst_pred(p2, y, z) in
        p_interp_op(o, p1, p2)
    | p_disj(p1, p2) =>
        let p1 = subst_pred(p1, y, z) in
        let p2 = subst_pred(p2, y, z) in
        p_disj(p1, p2)
    | p_conj(p1, p2) =>
        let p1 = subst_pred(p1, y, z) in
        let p2 = subst_pred(p2, y, z) in
        p_conj(p1, p2)
    | p_neg(p1) => 
        let p1 = subst_pred(p1, y, z) in
        p_neg(p1)
    | p_ite(p1, p2, p3) =>
        let p1 = subst_pred(p1, y, z) in
        let p2 = subst_pred(p2, y, z) in
        let p3 = subst_pred(p3, y, z) in
        p_ite(p1, p2, p3)
    end

fun subst_typ(t: typ, y: var, z: var): typ =
    match t with
    | t_refined(b, v, p) =>
        if v = y then t else t_refined(b, v, subst_pred(p, y, z)) 
    | t_func(x, s, t) =>
        let s = subst_typ(s, y, z) in
        let t = if x = y then t else subst_typ(t, y, z) in
        t_func(x, s, t)
    end
```

These functions are pretty standard.
We can then define the rules for subtyping:

```
rel sub(env, typ, typ)

sub(G, t_refined(B, V1, P1), t_refined(B, V2, P2)) :-
    ent(G, c_imp(V1, B, P1, c_pred(subst_pred(P2, V2, V1)))).

sub(G, t_func(X1, S1, T1), t_func(X2, S2, T2)) :-
    sub(G, S2, S1),
    sub((X2, S2) :: G, subst_typ(T1, X1, X2), T2).
```

### Type Synthesis

Given the machinery we have in place, the rules for type synthesis (Figure 3.5) fall into place nicely.

![Figure 3.5](./images/figure_3_5.png)

```
rel syn(env, expr, typ)

(* Declare relation for type checking, so we can refer to it *)
rel chk(env, expr, typ)

syn(G, e_var(X), T) :- lookup(X, G) = some(T).

(* Here we give an int n the type int{v : v = n} *)
syn(_G, e_int(N), t_refined(b_int, "v", P)) :-
    P = p_interp_op(o_eq, p_var("v"), p_int(N)).

syn(G, e_annot(E, T), T) :-
    wf(G, T, _k),
    chk(G, E, T).

syn(G, e_app(E, Y), subst_typ(T, X, Y)) :-
    syn(G, E, t_func(X, S, T)),
    chk(G, e_var(Y), S).
```

### Type Checking

The type checking rules themselves (Figure 3.6) are also straightforward.

![Figure 3.6](./images/figure_3_6.png)

```
chk(G, E, T) :-
    syn(G, E, S),
    sub(G, S, T).

chk(G, e_lambda(X, E), t_func(X, T1, T2)) :-
    chk((X, T1) :: G, E, T2).

chk(G, e_let(X, E1, E2), T2) :-
    syn(G, E1, T1),
    chk((X, T1) :: G, E2, T2).
```

## Running Some Examples


Now that we have all the logic in place, let's try to type check some terms!
First, we'll add a little machinery for running examples:

```
(* We'll populate this relation with numbered examples *)
rel ex(i32, env, expr, typ)

rel check_ex(i32)

check_ex(N) :-
    ex(N, G, E, T),
    chk(G, E, T).

(* This is a query that checks all examples; replace the _ with a number to check a particular example *)
:- check_ex(_).
```

### Checking Literals

Let's try a simple example first:

```
(* The type int{v: v = n} *)
fun lit_typ(n: i32): typ =
    t_refined(b_int, "v", p_interp_op(o_eq, p_var("v"), p_int(n)))

(*
    Expr
        42
    Type
        int{v: v = 42}
*)
ex(0, [], e_int(42), lit_typ(42)).
```

We can ask Formulog to dump the derived queries:

```
java -jar formulog.jar tutorial.flg --dump-query
```

Doing so, we'll see that `check_ex(0)` is derived:

```
==================== QUERY RESULTS (1) ====================
query:check_ex(0)
```

So, our type checker works on that example!

But maybe it accepts every term?
Let's try an example that should fail:

```
(*
    Expr
        42
    Type
        int{v: v = 43}
*)
ex(1, [], e_int(42), lit_typ(43)).
```

When we run Formulog now, we see that `check_ex(1)` is *not* derived; and so our type checker has successfully rejected that example!

### Checking Let Bindings

Here's an example involving a simple let binding:

```
(*
    Expr
        let z = 42 in z
    Type
        int{v: v = 42}
*)
ex(2, [], E, T) :-
    E = e_let("z", e_int(42), e_var("z")),
    T = lit_typ(42).
```

When we run this, we see that the fact `check_ex(2)` is not derived, which is wrong: this example should go through.
What's up?
We can debug this example by adding `print` statements to rules to essentially track the progress of the type checker.
For example, if the first of these print functions fires, but the second one does not, then we know that the entailment call failed: 

```
sub(G, t_refined(B, V1, P1), t_refined(B, V2, P2)) :-
    print(("sub ent 0", G, V1, P1, V2, P2)),
    ent(G, c_imp(V1, B, P1, c_pred(subst_pred(P2, V2, V1)))),
    print(("sub ent 1", G, V1, P1, V2, P2)).
```

Print is a function that takes any type (here a tuple) and returns `true` (a function can be used in a rule body as an atom if it returns a bool).
Admittedly, this is not a great debugging experience; hopefully we can come up with something better.
Nonetheless, with a little effort, we see that type checking fails on the recursive entailment rule (which faithfully implements the rule Ent-Ext in JV):

```
ent((X, t_refined(B, X, P)) :: G, C) :-
    ent(G, c_imp(X, B, P, C)).
```

The issue is that the judgment is too strict: it requires that the name of the variable in the context is the same as the name of the bound variable in the refinement.
We can fix this by adding another rule if the names are different; this rule changes the name of the variable in the refinement to match the name of the variable in the context, as long as that name does not already appear in the refinement:

```
fun appears(x: var, p: pred): bool =
    match p with
    | p_var(y) => x = y
    | p_bool(_) | p_int(_) => false
    | p_interp_op(_, p1, p2)
    | p_conj(p1, p2)
    | p_disj(p1, p2) =>
        appears(x, p1) || appears(x, p2)
    | p_neg(p1) => appears(x, p1)
    | p_ite(p1, p2, p3) =>
        appears(x, p1) || appears(x, p2) || appears(x, p3)
    end

(* An additional rule *)
ent((X, t_refined(B, Y, P)) :: G, C) :-
    X != Y && !appears(X, P),
    ent(G, c_imp(X, B, subst_pred(P, Y, X), C)).
```

Now the type checker works on this example!
(This isn't the most general solution: a better technique would be to create a fresh variable and substitute it for `Y` in `P` and `X` in `C`; however, this is good enough for now.)

### Checking Functions

Let's see if we can type a constant function:

```
(*
    Expr
        \y. 0 
    Type
        y:int{y: true} -> int{v: v = 0} 
*)
ex(5, [], e_lambda("y", e_int(0)), t_func("y", t_refined(b_int, "y", p_bool(true)), lit_typ(0))).
```

It works!
How about if we bind that function, but do not actually use it?
(Note that lambdas need to be annotated with a type using the `e_annot` constructor, as there are no rules for synthesizing a type for a lambda.)

```
(*
    Expr
        let z = \y. 0 in
        let x = 42 in
        x
    Type
        int{v: v = 42}
*)
ex(6, [], E, T) :-
    Lam_type = t_func("y", t_refined(b_int, "y", p_bool(true)), lit_typ(0)),
    E1 = e_let("x", e_int(42), e_var("x")),
    E = e_let("z", e_annot(e_lambda("y", e_int(0)), Lam_type), E1),
    T = lit_typ(42).
```

This fails!
What gives?
If we do some more debugging, we see that entailment is once again an issue: there is no rule for what to do if there is a variable in the context with a function type (in this case, the program variable "z").
We can fix that by adding another entailment rule that skips over the binding, as long as the bound variable does not appear free in the constraint:

```
fun is_free(x: var, c: constraint): bool =
    match c with
    | c_pred(p) => appears(x, p)
    | c_conj(c1, c2) => is_free(x, c1) || is_free(x, c2)
    | c_imp(y, _, p, c1) =>
        x != y && (appears(x, p) || is_free(x, c1))
    end

(* An additional rule *)
ent((X, t_func(_, _, _)) :: G, C) :-
    !is_free(X, C),
    ent(G, C).
```

Now the example works :)

How about if we apply the function?

```
(*
    Expr
        let z = \y. 0 in
        let x = 42 in
        z x
    Type
        int{v: v = 0}
*)
ex(7, [], E, T) :-
    Lam_type = t_func("y", t_refined(b_int, "y", p_bool(true)), lit_typ(0)),
    E1 = e_let("x", e_int(42), e_app(e_var("z"), "x")),
    E = e_let("z", e_annot(e_lambda("y", e_int(0)), Lam_type), E1),
    T = lit_typ(0).
```

It works!

### Checking Addition

So far, our examples have not included very interesting refinements.
Let's try to type check an expression involving addition.
Since our language of expressions does not actually include operations like addition, we will include an "add" function in the context with the appropriate type.

```
(* The type of the add function *)
const add_typ: typ =
    let add = p_interp_op(o_add, p_var("x"), p_var("y")) in
    let eq = p_interp_op(o_eq, p_var("v"), add) in
    let r = t_refined(b_int, "v", eq) in
    let t = t_func("y", t_refined(b_int, "v", p_bool(true)), r) in
    let s = t_refined(b_int, "v", p_bool(true)) in
    t_func("x", s, t)

(*
    Context
        add |-> x:int{v: true} -> (y:int{v: true} -> int{v: v = x + y})
        one |-> int{v: v = 1}
    Expr
        let z = 41 in
        add z one
    Type
        int{v: v = 42}
*)
ex(8, G, E, T) :-
    G = [("add", add_typ), ("one", lit_typ(1))],
    E = e_let("z", e_int(41), e_app(e_app(e_var("add"), "z"), "one")),
    T = lit_typ(42).
```

It works!
We've been able to prove, in the type system, that our expression evaluates to 42.

## Exercises

Adventurous readers might want to take on these extra exercises.

### Add an Uninterpreted Operation

Our language of predicates includes interpreted operations (like addition and equality), but no uninterpreted operations (the grammar of JV includes both).
Add a new `pred` constructor `p_gcd(pred, pred)` that represents the greatest common denominator of two terms.
When a `p_gcd` predicate is converted to an SMT term in the function `pred2smt`, emit an uninterpreted function term.
SMT-level uninterpreted functions can be declared in Formulog using syntax like:

```
uninterpreted fun foo(i32 smt, string smt): bool smt
```

You'll also have to update rules/functions as appropriate, to handle the new constructor case.

### Add Branches and Recursion

Implement the additional rules for branches and recursion in JV Sections 4.2 and 4.3.
We have not tried this ourselves; let us know (by raising a [GitHub issue](https://github.com/HarvardPL/formulog/issues/new)) if you run into difficulties!

From skimming the new rules, the trickiest part appears to be creating a fresh variable `y` in the Chk-If rule.
One approach you might consider is changing the type of variables from `string` to `val sym` (i.e., a `val`-valued SMT variable):

```
type var = val sym
```

This will require a bunch of updates in the existing code (a bit of a pain), but it has the advantage that it is now very easy to create a fresh variable.
For example, say that you have a context `g` and an expr `e`: the variable `#{(g, e)}[val]` is guaranteed to not occur in either `g` or `e`---i.e., it's fresh.
(Here, we are using the tuple `(g, e)` as the "name" of the variable.)
We have found this trick to be useful in implementing more complex type systems. 

### Check Out More Complex Formulog Examples

For our [Formulog publications]({{ site.base_url }}{% link pubs.md %}), we have built three substantial, relatively sophisticated SMT-based case studies.
After going through this tutorial, you might find it interesting to check out the code for these case studies.
While the analyses are more complex than the tutorial example (and, admittedly, not as well documented as they could be), this tutorial will have hopefully armed you with the information to understand a lot of what's happening in them.

- [Dminor](https://github.com/aaronbembenek/making-formulog-fast/blob/main/benchmarks/dminor/bench.flg) [2]: a refinement type checker that allows dynamic type tests, so that types can refer to expressions, and expressions can refer to types.
Type checking also involves proving that expressions are pure, which requires termination checking.
- [Scuba](https://github.com/aaronbembenek/making-formulog-fast/blob/main/benchmarks/scuba/bench.flg) [3]: a context-sensitive, bottom-up points-to analysis for Java that uses SMT formulas to summarize the effects of methods on the points-to graph.
- [Symex](https://github.com/aaronbembenek/making-formulog-fast/blob/main/benchmarks/symex/bench.flg): a KLEE-style [4] symbolic executor for a fragment of LLVM bitcode corresponding to simple C programs with loops and arrays.

## Conclusions

In this tutorial, we've seen how to mechanize the formal specification of an interesting program analysis---the declarative rules for bidirectional refinement type checking---by encoding that specification directly in Formulog.
It's neat to be able to program so close to the formal specification; as we've seen, doing so has even allowed us to identify a few possible gaps in the inference rules (i.e., the missing rules for entailment).

Furthermore, now that you have a Formulog implementation of the analysis, you can rely on Formulog's language infrastructure to apply both high-level and low-level optimizations to the analysis.
For example, Formulog's parallel evaluation techniques can speed up type checking in the presence of multiple code units.
Additionally, the [compiler]({{ site.base_url }}{% link eval_modes/compile.md %}) from Formulog to Soufflé makes it possible to automatically derive a decently efficient C++ version of the type checker.

We hope you have enjoyed this dive into Formulog!
As we mentioned earlier, please raise a [GitHub issue](https://github.com/HarvardPL/formulog/issues/new) for questions, comments, and feedback :)

## References

[1] Ranjit Jhala and Niki Vazou. 2020. Refinement Types: A Tutorial. arXiv:2010.07763v1. <https://arxiv.org/abs/2010.07763v1>

[2] Gavin M. Bierman, Andrew D. Gordon, Cătălin Hriţcu, and David Langworthy. 2012. Semantic Subtyping with an SMT Solver. Journal of Functional Programming 22, 1 (2012), 31–105. <https://doi.org/10.1017/S0956796812000032>

[3] Yu Feng, Xinyu Wang, Isil Dillig, and Thomas Dillig. 2015. Bottom-up Context-Sensitive Pointer Analysis for Java. In Proceedings of the 13th Asian Symposium on Programming Languages and Systems. 465–484. <https://doi.org/10.1007/978-3-319-26529-2_25>

[4] Cristian Cadar, Daniel Dunbar, and Dawson Engler. 2008. KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs. In Proceedings of the 8th USENIX Conference on Operating Systems Design and Implementation. 209–224. <https://www.usenix.org/legacy/event/osdi08/tech/full_papers/cadar/cadar.pdf>


================================================
FILE: examples/greeting.flg
================================================
(*-
 * #%L
 * Formulog
 * %%
 * Copyright (C) 2018 - 2019 President and Fellows of Harvard College
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 *)

@edb rel entity(string)
entity("Alice").
entity("Bob").
entity("World").

rel greeting(string)
greeting(Y) :-
  entity(X),
  some(M) = get_model([`#y[string] #= str_concat("Hello, ", X)`], none),
  some(Y) = query_model(#y[string], M).


================================================
FILE: examples/liquid_types.flg
================================================
(*-
 * #%L
 * Formulog
 * %%
 * Copyright (C) 2018 - 2019 President and Fellows of Harvard College
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 *)

(*******************************************************************************
  LIQUID_TYPES.FLG

  This file has the implementation of a type checker for a simple language with
  refinement types.
*******************************************************************************)

type tvar = string

type var = string sym

type label = string

type op =
  | op_not
  | op_or
  | op_and
  | op_eqb

type base =
  | base_bool
  
type typ = 
  | typ_tvar(tvar)
  | typ_fun(var, typ, typ)
  | typ_forall(tvar, typ)
  | typ_ref(var, base, exp)

and exp = 
  | exp_var(var)
  | exp_bool(bool)
  | exp_op(op)
  | exp_lam(var, typ, exp)
  | exp_tlam(tvar, exp)
  | exp_app(exp, exp)
  | exp_tapp(exp, typ)

fun append(L1 : 'a list, L2 : 'a list) : 'a list =
  match L1 with
  | [] => L2
  | X :: L1rest => X :: append(L1rest, L2)
  end

fun remove(X : 'a, L : 'a list) : 'a list =
  match L with
  | [] => []
  | Y :: Lrest  => if X = Y then remove(X, Lrest) else Y :: remove(X, Lrest)
  end

fun elem(X : 'a, L : 'a list) : bool =
  match L with
  | [] => false
  | Y :: Lrest => X = Y || elem(X, Lrest)
  end

const x : var = #x[string]
const y : var = #y[string]
const b : var = #b[string]
const b1 : var = #b1[string]
const b2 : var = #b2[string]
const v : var = #v[string]

fun fresh_for(NAME : var, VARS : var list) : var =
  if elem(NAME, VARS)
  then (* okay, we have work to do *)
       #{VARS}[string] 
  else (* we're fine---the name is already fresh *)
       NAME

fun typ_freevars(T : typ) : var list =
  match T with
  | typ_tvar(_) => []
  | typ_fun(X, T1, T2) => append(typ_freevars(T1), remove(X, typ_freevars(T2)))
  | typ_forall(_, Tinner) => typ_freevars(Tinner)
  | typ_ref(X, _B, Eref) => remove(X, exp_freevars(Eref))
  end

and exp_freevars(E : exp) : var list =
  match E with
  | exp_var(X) => [X]
  | exp_bool(_) => []
  | exp_lam(X, T, Elam) => append(typ_freevars(T), remove(X, exp_freevars(Elam)))
  | exp_tlam(_, Etlam) => exp_freevars(Etlam)
  | exp_app(E1, E2) => append(exp_freevars(E1), exp_freevars(E2))
  | exp_tapp(Etapp, Ttapp) => append(exp_freevars(Etapp), typ_freevars(Ttapp))
  end

(* SUGAR *)
fun typ_base(B : base) : typ = typ_ref(v, B, exp_bool(true)).
fun typ_simple(Tdom : typ, Tcod : typ) : typ = typ_fun(v, Tdom, Tcod)

fun exp_not(E : exp) : exp =
  exp_app(exp_op(op_not), E).
fun exp_or(E1 : exp, E2 : exp) : exp =
  exp_app(exp_app(exp_op(op_or), E1), E2).
fun exp_and(E1 : exp, E2 : exp) : exp =
  exp_app(exp_app(exp_op(op_and), E1), E2).
fun exp_eqb(T : typ, E1 : exp, E2 : exp) : exp =
  exp_app(exp_app(exp_tapp(exp_op(op_eqb), T), E1), E2)

fun typ_isref(T : typ) : bool =
  match T with
  | typ_ref(_, _, _) => true
  | _ => false
  end

fun typ_op(O : op) : typ =
  match O with
  | op_not => typ_fun(b, typ_base(base_bool),
                           typ_base(base_bool))
  | op_or => typ_fun(b1, typ_base(base_bool),
             typ_fun(b2, typ_base(base_bool),
                           typ_base(base_bool)))
  | op_and => typ_fun(b1, typ_base(base_bool),
              typ_fun(b2, typ_base(base_bool),
                            typ_base(base_bool)))
  | op_eqb => typ_forall("A",
              typ_fun(x, typ_base(base_bool),
              typ_fun(y, typ_base(base_bool),
                           typ_ref(v,base_bool,
                                   exp_eqb(typ_tvar("A"), 
                                           exp_var(v),
                                           exp_app(exp_app(exp_op(op_eqb),
                                                           exp_var(x)),
                                                   exp_var(y)))))))
  end                                        


fun typ_subst(X : var, E : exp, T : typ) : typ =
  match T with
  | typ_tvar(_) => T
  | typ_fun(Y, T1, T2) =>
    let Yfresh = fresh_for(Y, X::append(exp_freevars(E), typ_freevars(T2))) in
    let T2fresh = if Y = Yfresh then T2 else typ_subst(Y, exp_var(Yfresh), T2) in
    typ_fun(Yfresh, 
            typ_subst(X, E, T1),
            typ_subst(X, E, T2fresh))
  | typ_forall(A, Tinner) =>
    typ_forall(A, typ_subst(X, E, Tinner))
  | typ_ref(Y, B, Eref) =>
    let Yfresh = fresh_for(Y, X::append(exp_freevars(E), exp_freevars(Eref))) in
    let Ereffresh = if Y = Yfresh then Eref else exp_subst(Y, exp_var(Yfresh), Eref) in
    typ_ref(Yfresh,
            B,
            exp_subst(X, E, Ereffresh))
  end

and exp_subst(X: var, E : exp, Etgt : exp) : exp =
  match Etgt with
  | exp_var(Y) => if X = Y then E else Etgt
  | exp_bool(_) => Etgt
  | exp_op(_) => Etgt
  | exp_lam(Y, Tlam, Elam) =>
    let Yfresh = fresh_for(Y, X::append(typ_freevars(Tlam), exp_freevars(Elam))) in
    let Elamfresh = if Y = Yfresh then Elam else exp_subst(Y, exp_var(Yfresh), Elam) in
    exp_lam(Yfresh,
            typ_subst(X, E, Tlam),
            Elamfresh)
  | exp_tlam(A, Etlam) =>
    exp_tlam(A, exp_subst(X, E, Etlam))
  | exp_app(E1, E2) => 
    exp_app(exp_subst(X, E, E1),
            exp_subst(X, E, E2))
  | exp_tapp(Etapp, T) => 
    exp_tapp(exp_subst(X, E, Etapp), typ_subst(X, E, T))
  end

fun typ_tsubst(A : tvar, T : typ, Ttgt : typ) : typ =
  match T with
  | typ_tvar(B) => if A = B then T else Ttgt
  | typ_fun(X, T1, T2) => 
    typ_fun(X, typ_tsubst(A, T, T1), typ_tsubst(A, T, T2))
  | typ_forall(B, Tinner) =>
    let Tnew = if A = B then Tinner else typ_tsubst(A, T, Tinner) in
    typ_forall(B, Tnew)
  | typ_ref(X, B, Eref) =>
    typ_ref(X, B, exp_tsubst(A, T, Eref))
  end

and exp_tsubst(A : tvar, T : typ, E : exp) : exp =
  match E with
  | exp_var(_) | exp_bool(_) => E
  | exp_op(_) => E
  | exp_lam(X, Tlam, Elam) =>
    exp_lam(X, typ_tsubst(A, T, Tlam), exp_tsubst(A, T, Elam))
  | exp_tlam(B, Etlam) =>
    let Enew = if A = B then Etlam else exp_tsubst(A, T, Etlam) in
    exp_tlam(B, Enew)
  | exp_app(E1, E2) =>
    exp_app(exp_tsubst(A, T, E1), exp_tsubst(A, T, E2))
  | exp_tapp(Etapp, Ttapp) =>
    exp_tapp(exp_tsubst(A, T, Etapp), typ_tsubst(A, T, Ttapp))
  end

type ctx  = 
  | ctx_empty
  | ctx_var(ctx, var, typ)
  | ctx_tvar(ctx, tvar)
  | ctx_exp(ctx, exp)

fun lookup(X : var, G : ctx) : typ option =
  match G with
  | ctx_empty => none
  | ctx_var(Grest, Y, T) => if X = Y then some(T) else lookup(X, Grest)
  | ctx_tvar(Grest, _) => lookup(X, Grest)
  | ctx_exp(Grest, _) => lookup(X, Grest)
  end

fun bound_tvar(A : tvar, G : ctx) : bool =
  match G with
  | ctx_empty => false
  | ctx_var(Grest, _, _) => bound_tvar(A, Grest)
  | ctx_tvar(Grest, B) => A = B || bound_tvar(A, Grest)
  | ctx_exp(Grest, _) => bound_tvar(A, Grest)
  end

@topdown
rel encode_ctx(ctx, bool smt)
@topdown
rel encode_exp(exp, bool smt)

@topdown
rel sub(ctx, typ, typ)
@topdown
rel wf_ctx(ctx)
@topdown
rel wf_typ(ctx, typ)
@topdown
rel wf_exp(ctx, exp, typ)
@topdown
rel synth(ctx, exp, typ)
@topdown
rel check(ctx, exp, typ)

(*******************************************************************************)
(* SMT ENCODING ****************************************************************)

encode_ctx(ctx_empty, `true`).

encode_ctx(ctx_tvar(Grest, _), Phi) :-
  encode_ctx(Grest, Phi).

encode_ctx(ctx_exp(Grest, E), `Phirest /\ PhiE`) :-
  encode_ctx(Grest, Phirest),
  encode_exp(E, PhiE).

encode_ctx(ctx_var(Grest, X, typ_ref(Y, _B, E)), `Phirest /\ PhiE`) :-
  encode_ctx(Grest, Phirest),
  Eprime = exp_subst(Y, exp_var(X), E),
  encode_exp(Eprime, PhiE).

encode_ctx(ctx_var(Grest, _, T), Phirest) :-
  encode_ctx(Grest, Phirest),
  !typ_isref(T).

encode_exp(exp_var(X), V) :-
  V = `#{X}[bool]`. 
  (* We would need a more sophisticated encoding if there were other types *)

encode_exp(exp_bool(true), `true`).

encode_exp(exp_bool(false), `false`).

encode_exp(exp_app(exp_op(op_not), E), `~Phi`) :-
  encode_exp(E, Phi).

encode_exp(exp_app(exp_app(exp_op(op_and), E1), E2), `Phi1 /\ Phi2`) :-
  encode_exp(E1, Phi1),
  encode_exp(E2, Phi2).

encode_exp(exp_app(exp_app(exp_op(op_or), E1), E2), `Phi1 \/ Phi2`) :-
  encode_exp(E1, Phi1),
  encode_exp(E2, Phi2).

encode_exp(exp_app(exp_app(exp_tapp(exp_op(op_eqb), _T), E1), E2),
           `Phi1 #= Phi2`) :-
  encode_exp(E1, Phi1),
  encode_exp(E2, Phi2).

(*******************************************************************************)
(* SUBTYPING *******************************************************************)

sub(G, typ_ref(X, B, E1), typ_ref(Y, B, E2)) :-
  wf_ctx(G),
  exp_subst(Y, exp_var(X), E2) = E2prime,
  encode_ctx(G, PhiG),
  encode_exp(E1, Phi1),
  encode_exp(E2prime, Phi2),
  is_valid(`PhiG /\ Phi1 ==> Phi2`).

sub(G, typ_tvar(A), typ_tvar(A)) :-
  wf_ctx(G).

sub(G, typ_fun(X, T11, T12), typ_fun(Y, T21, T22)) :-
  sub(G, T21, T11),
  typ_subst(Y, exp_var(X), T22) = T22prime,
  sub(ctx_var(G, X, T21), T12, T22prime).

sub(G, typ_forall(A, T1), typ_forall(B, T2)) :-
  typ_tsubst(B, typ_tvar(A), T2) = T2prime,
  sub(ctx_tvar(G, A), T1, T2prime). 

(*******************************************************************************)
(* WELL FORMEDNESS OF CONTEXTS *************************************************)

wf_ctx(ctx_empty).
wf_ctx(ctx_var(G, _X, T)) :-
  wf_ctx(G),
  wf_typ(G, T).
wf_ctx(ctx_tvar(G, _)) :-
  wf_ctx(G).

(*******************************************************************************)
(* WELL FORMEDNESS OF TYPES ****************************************************)

wf_typ(G, typ_tvar(A)) :-
  wf_ctx(G),
  bound_tvar(A, G).

wf_typ(G, typ_fun(X, T1, T2)) :-
  wf_typ(G, T1),
  wf_typ(ctx_var(G, X, T1), T2).

wf_typ(G, typ_forall(A, T)) :-
  wf_typ(ctx_tvar(G, A), T).

wf_typ(G, typ_ref(_X, _B, exp_bool(true))) :-
  wf_ctx(G).

wf_typ(G, typ_ref(X, B, E)) :-
  E != exp_bool(true),
  wf_typ(G, typ_base(B)),
  check(ctx_var(G,X,typ_base(B)), E, typ_base(base_bool)).

(*******************************************************************************)
(* WELL FORMEDNESS OF TERMS (i.e., TYPING) *************************************)

check(G, E, T) :-
  synth(G, E, Tprime),
  sub(G, Tprime, T).

synth(G, exp_var(X), T) :-
  wf_ctx(G), 
  lookup(X, G) = some(T),
  !typ_isref(T).

synth(G, exp_var(X), typ_ref(Vfresh, B, exp_eqb(T, exp_var(Vfresh), exp_var(V)))) :-
  wf_ctx(G),
  lookup(X, G) = some(T),
  T = typ_ref(V, B, _E),
  fresh_for(v, typ_freevars(T)) = Vfresh.

synth(G, exp_bool(true), typ_ref(v, base_bool, exp_var(v))) :-
  wf_ctx(G).

synth(G, exp_bool(false), typ_ref(v, base_bool, exp_app(exp_op(op_not), exp_var(v)))) :-
  wf_ctx(G).

synth(G, exp_op(O), typ_op(O)) :-
  wf_ctx(G).
  
synth(G, exp_lam(X, T1, E), T) :-
  wf_typ(G, T1),
  synth(ctx_var(G, X, T1), E, T2),
  typ_fun(X, T1, T2) = T.

synth(G, exp_app(E1, E2), T) :-
  synth(G, E1, typ_fun(X, T1, T2)),
  check(G, E2, T1),
  typ_subst(X, E2, T2) = T.

synth(G, exp_tapp(E, Targ), T) :-
  synth(G, E, typ_forall(A, Tinner)),
  typ_tsubst(A, Targ, Tinner) = T.

(* Try uncommenting these different queries (one query allowed at a time); you
might want to run Formulog with the `--dump-query` option. *)

(*
:- check(ctx_empty, exp_bool(true), typ_ref(v, base_bool, exp_var(v))).
*)

(*
:- check(ctx_empty, exp_bool(true), typ_base(base_bool)).
*)

(*
:- wf_typ(ctx_empty, typ_base(base_bool)).
*)

(*
:- check(ctx_var(ctx_empty, x, typ_base(base_bool)), 
         exp_var(x),
         typ_base(base_bool)).
*)

(*
:- wf_typ(ctx_empty, typ_ref(x, base_bool, exp_var(x))).
*)

:- wf_typ(ctx_empty, typ_ref(x, base_bool, exp_app(exp_op(op_not), exp_var(x)))).



================================================
FILE: examples/symeval.flg
================================================
(*-
 * #%L
 * Formulog
 * %%
 * Copyright (C) 2018 - 2019 President and Fellows of Harvard College
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 *)

(*******************************************************************************
  SYMEVAL.FLG

  This file has the implementation of a bounded symbolic evaluator for a simple
  imperative language.
*******************************************************************************)

type ('k, 'v) map = ('k * 'v) list

fun get(K:'k, Map:('k, 'v) map) : 'v option =
  match Map with
  | [] => none
  | (K2, V) :: Rest => if K = K2 then some(V) else get(K, Rest)
  end

fun put(K:'k, V:'v, Map:('k, 'v) map) : ('k, 'v) map = (K, V) :: Map

type node = i32
type var = string

type cond =
  | cond_eq
  | cond_ne
  | cond_lt
  | cond_le
  | cond_gt
  | cond_ge

type binop =
  | binop_add
  | binop_mul
  | binop_div
  | binop_rem
    
type unop =
  | unop_neg

type inst =
  | inst_jmp(cond, var, var, node)
  | inst_goto(node)
  | inst_binop(var, binop, var, var)
  | inst_unop(var, unop, var)
  | inst_fail
  | inst_assign(var, var)

type val =
  | v_conc(i32)
  | v_symb(bv[32] sym)

type store = (var, val) map
type state = (store * bool smt)

@edb rel fall_thru_succ(node, node)
@edb rel start(node, store)
@edb rel stmt(node, inst)
rel reach(node, state, i32)
rel failed_assert(node, state)
rel stepping_to(node, state, i32)
@edb rel max_steps(i32)

fun get_store(State:state) : store =
  match State with (Store, _) => Store end
  
fun get_constraints(State:state) : bool smt =
  match State with (_, Constraints) => Constraints end
  
fun update_store(Reg:var, Val:val, State:state) : state =
  let (Store, Constraints) = State in
  let New_store = put(Reg, Val, Store) in
  (New_store, Constraints)

fun update_constraints(Constraint:bool smt, State:state) : state =
  let (Store, Constraints) = State in
  (Store, `Constraint /\ Constraints`)

fun flip_cond(Cond:cond) : cond =
  match Cond with
  | cond_eq => cond_ne
  | cond_ne => cond_eq
  | cond_lt => cond_ge
  | cond_le => cond_gt
  | cond_gt => cond_le
  | cond_ge => cond_lt
  end

fun handle_unop(Dest:var, Op:unop, Val:var, State:state) : state =
  let Store = get_store(State) in
  match get(Val, Store) with
  | some(v_conc(X)) =>
    let Res =
      match Op with
      | unop_neg => -X
      end in
    update_store(Dest, v_conc(Res), State)
  | some(v_symb(Val)) =>
    let X = #{State}[bv[32]] in
    let Neg =
      match Op with
      | unop_neg => `bv_neg(Val)`
      end in
    let State = update_constraints(`X #= Neg`, State) in
    update_store(Dest, v_symb(X), State)
  end

fun coerce_symbolic_val(Val:val) : bv[32] smt =
  match Val with v_conc(X) | v_symb(X) => `X` end

fun handle_binop(Dest:var, Op:binop, Val1:var, Val2:var, State:state) : state =
    let Store = get_store(State) in
    let some(Val1) = get(Val1, Store) in
    let some(Val2) = get(Val2, Store) in
    match (Val1, Val2) with
    | (v_conc(X1), v_conc(X2)) =>
      let Res =
        match Op with
        | binop_add => X1 + X2
        | binop_mul => X1 * X2
        | binop_div => X1 / X2
        | binop_rem => X1 % X2
        end in
      update_store(Dest, v_conc(Res), State)
    | _ =>
      let X = #{State}[bv[32]] in
      let Val1 = coerce_symbolic_val(Val1) in
      let Val2 = coerce_symbolic_val(Val2) in
      let Res =
        match Op with
        | binop_add => `bv_add(Val1, Val2)`
        | binop_mul => `bv_mul(Val1, Val2)`
        | binop_div => `bv_sdiv(Val1, Val2)`
        | binop_rem => `bv_srem(Val1, Val2)`
        end in
      let State = update_constraints(`X #= Res`, State) in
      update_store(Dest, v_symb(X), State)
    end

fun handle_cond(Cond:cond, Reg1:var, Reg2:var, State:state) : state option =
  let (Store, Constraints) = State in
  let some(Val1) = get(Reg1, Store) in
  let some(Val2) = get(Reg2, Store) in
  match (Val1, Val2) with
  | (v_conc(X1), v_conc(X2)) =>
    let Feasible =
      match Cond with
      | cond_eq => X1 = X2
      | cond_ne => X1 != X2
      | cond_lt => X1 < X2
      | cond_le => X1 <= X2
      | cond_gt => X1 > X2
      | cond_ge => X1 >= X2
      end in
    if Feasible then some(State) else none
  | _ => 
    let Val1 = coerce_symbolic_val(Val1) in
    let Val2 = coerce_symbolic_val(Val2) in
    let Constraint =
      match Cond with
      | cond_eq => `Val1 #= Val2`
      | cond_ne => `~(Val1 #= Val2)`
      | cond_lt => `bv_slt(Val1, Val2)`
      | cond_le => `~bv_sgt(Val1, Val2)`
      | cond_gt => `bv_sgt(Val1, Val2)`
      | cond_ge => `~bv_slt(Val1, Val2)`
      end in
    let New_constraints = `Constraint /\ Constraints` in
    if is_sat(New_constraints) then
      let New_state = (Store, New_constraints) in
      some(New_state)
    else none
  end

stepping_to(Node, (Store, `true`), 0) :-
  start(Node, Store).

stepping_to(Succ, New_state, D) :-
  fall_thru_succ(Node, Succ),
  stmt(Node, inst_assign(Dest, Val)),
  reach(Node, State, D),
  some(X) = get(Val, get_store(State)),
  New_state = update_store(Dest, X, State).

stepping_to(Succ, New_state, D) :-
  fall_thru_succ(Node, Succ),
  stmt(Node, inst_unop(Dest, Op, Val)),
  reach(Node, State, D),
  New_state = handle_unop(Dest, Op, Val, State).

stepping_to(Succ, New_state, D) :-
  fall_thru_succ(Node, Succ),
  stmt(Node, inst_binop(Dest, Op, Val1, Val2)),
  reach(Node, State, D),
  New_state = handle_binop(Dest, Op, Val1, Val2, State).

stepping_to(Succ, New_state, D) :-
  stmt(Node, inst_jmp(Cond, Val1, Val2, Succ)),
  reach(Node, State, D),
  some(New_state) = handle_cond(Cond, Val1, Val2, State).

stepping_to(Succ, New_state, D) :-
  fall_thru_succ(Node, Succ),
  stmt(Node, inst_jmp(Cond, Val1, Val2, _)),
  reach(Node, State, D),
  some(New_state) = handle_cond(flip_cond(Cond), Val1, Val2, State).

stepping_to(Succ, State, D) :-
  stmt(Node, inst_goto(Succ)),
  reach(Node, State, D).

max_steps(10).

reach(Node, State, D + 1) :-
  stepping_to(Node, State, D),
  max_steps(X),
  D < X.

failed_assert(Node, State) :-
  stmt(Node, inst_fail),
  reach(Node, State, _).

(* our query... comment this out to exhaustively explore the program states *)
:- failed_assert(_N, _S).

fun vc(N:i32) : val = v_conc(N).
fun vs(X:string) : val = v_symb(#{X}[bv[32]]).

(* example 01 *)

(*
start(0, []).
*)

(* example 02

    x = 21 + 21;
*)

(*
start(0, [("21", vc(21))]).
stmt(0, inst_binop("x", binop_add, "21", "21")).
fall_thru_succ(0, 1).
*)

(* example 03

    x = mksym();
    if (x != x) {
        fail();
    }
*)

(*
start(0, [("x", vs("x"))]).
stmt(0, inst_jmp(cond_eq, "x", "x", 2)).
stmt(1, inst_fail).
fall_thru_succ(0, 1).
*)

(* example 04

    x = mksym();
    if (x == 0) {
        x = x + 1; 
    }
    if (x == 0) {
        fail();
    }
*)

(*
start(0, [("0", vc(0)), ("1", vc(1)), ("x", vs("x"))]).
stmt(0, inst_jmp(cond_ne, "x", "0", 2)).
stmt(1, inst_binop("x", binop_add, "x", "1")).
stmt(2, inst_jmp(cond_ne, "x", "0", 4)).
stmt(3, inst_fail).
fall_thru_succ(0, 1).
fall_thru_succ(1, 2).
fall_thru_succ(2, 3).
*)

(* example 05

    x = mksym();
    y = mksym();
    if (x < 0) {
        x = -x;
    }
    if (y < 0) {
        y = -y;
    }
    z = x + y;
    if (z < 0) {
        fail();
    } 
*)

(*
start(2, [("0", vc(0)), ("x", vs("x")), ("y", vs("y"))]).
stmt(2, inst_jmp(cond_ge, "x", "0", 4)).
stmt(3, inst_unop("x", unop_neg, "x")).
stmt(4, inst_jmp(cond_ge, "y", "0", 6)).
stmt(5, inst_unop("y", unop_neg, "y")).
stmt(6, inst_binop("z", binop_add, "x", "y")).
stmt(7, inst_jmp(cond_ge, "z", "0", 9)).
stmt(8, inst_fail).
fall_thru_succ(0, 1).
fall_thru_succ(1, 2).
fall_thru_succ(2, 3).
fall_thru_succ(3, 4).
fall_thru_succ(4, 5).
fall_thru_succ(5, 6).
fall_thru_succ(6, 7).
fall_thru_succ(7, 8).
*)

(* example 06

    euclid's gCD algorithm
    
    x0 = 0;
    x1 = ...;
    x2 = ...;
    while (x2 != x0) {
        x3 = x2;
        x2 = x1 % x2;
        x1 = x3;
    }
*)

(*
start(0, [("x0", vc(0)), ("x2", vc(1071)), ("x1", vc(462))]).
stmt(0, inst_jmp(cond_eq, "x2", "x0", 1)).
stmt(2, inst_assign("x3", "x2")).
stmt(3, inst_binop("x2", binop_rem, "x1", "x2")).
stmt(4, inst_assign("x1", "x3")).
stmt(5, inst_goto(0)).
fall_thru_succ(0, 2).
fall_thru_succ(2, 3).
fall_thru_succ(3, 4).
fall_thru_succ(4, 5).
*)

(* example 07

    x0 = 42;
    if (x0 == x0) {
      fail();
    } else {
      x0 = x0;
      x0 = x0;
      x0 = x0;
    }
*)

(*
stmt(0, inst_jmp(cond_ne, "x", "x", 2)).
stmt(1, inst_fail).
stmt(2, inst_assign("x", "x")).
stmt(3, inst_assign("x", "x")).
stmt(4, inst_assign("x", "x")).
fall_thru_succ(0, 1).
fall_thru_succ(2, 3).
fall_thru_succ(3, 4).
start(0, [("x", vc(42))]).
*)

(* example 08

  x = mksym();
  while (x == x) {
    // do nothing    
  }
  fail();

*)

(*
stmt(1, inst_jmp(cond_ne, "x", "x", 2)).
fall_thru_succ(0, 1).
fall_thru_succ(1, 1).
stmt(2, inst_fail).
start(1, [("x", vs("x"))]).
*)

(* example 09

  goto label2;
  label1:
  goto label1;
  label2:
  fail();

*)

(*
stmt(0, inst_goto(2)).
stmt(1, inst_goto(1)).
stmt(2, inst_fail).
start(0, []).
*)

(* example 10 
  
  x = mksym();
  y = mksym();
  goto label;
  while (x == y) {
    // do nothing
  }
  label:
  fail();

*)

(*
stmt(0, inst_goto(2)).
stmt(1, inst_jmp(cond_ne, "x", "y", 2)).
stmt(2, inst_fail).
fall_thru_succ(1, 1).
start(0, [("x", vs("x")), ("y", vs("y"))]).
*)

(* example 11 
  
  x = mksym();
  y = mksym();
  while (x == y) {
    // do nothing
  }
  fail();

*)

(*
stmt(0, inst_jmp(cond_ne, "x", "y", 1)).
stmt(1, inst_fail).
fall_thru_succ(0, 0).
start(0, [("x", vs("x")), ("y", vs("y"))]).
*)

(* example 12

  goto end;
  while (true) {};
  fail();

*)

(*
stmt(0, inst_goto(2)).
stmt(1, inst_jmp(cond_ne, "1", "1", 2)).
stmt(2, inst_fail).
fall_thru_succ(1, 1).
start(0, [("1", vc(1))]).
*)

(* example 13 

    x0 = mksymb();
    if (x0 == x0) {
      fail();
    } else {
      x0 = x0;
      x0 = x0;
      x0 = x0;
    }
*)

(*
stmt(0, inst_jmp(cond_ne, "x", "x", 2)).
stmt(1, inst_fail).
stmt(2, inst_assign("x", "x")).
stmt(3, inst_assign("x", "x")).
stmt(4, inst_assign("x", "x")).
fall_thru_succ(0, 1).
fall_thru_succ(2, 3).
fall_thru_succ(3, 4).
start(0, [("x", vs("x"))]).
*)

(* example 14 

    x0 = mksymb();
    if (x0 != x0) {
      x0 = x0;
      x0 = x0;
      x0 = x0;
    } else {
      fail();
    }
*)

(*
stmt(0, inst_jmp(cond_eq, "x", "x", 1)).
stmt(1, inst_fail).
stmt(2, inst_assign("x", "x")).
stmt(3, inst_assign("x", "x")).
stmt(4, inst_assign("x", "x")).
fall_thru_succ(0, 2).
fall_thru_succ(2, 3).
fall_thru_succ(3, 4).
start(0, [("x", vs("x"))]).
*)

(* example 15 
  
  x = mksym();
  y = mksym();
  while (x != y) {
    x = x + x;
  }
  fail();

*)

(*
stmt(0, inst_jmp(cond_eq, "x", "y", 2)).
stmt(1, inst_binop("x", binop_add, "x", "x")).
stmt(2, inst_fail).
fall_thru_succ(0, 1).
fall_thru_succ(1, 0).
start(0, [("x", vs("x")), ("y", vs("y"))]).
*)

(* example 15 
  
  x = x + x;
  x = x + x;
  x = x + x;
  x = x + x;
  x = x + x;
  x = x + x;
  x = x + x;
  x = x + x;
  x = x + x;
  x = x + x;
  fail();

*)

(*
stmt(0, inst_binop("x", binop_add, "x", "x")).
stmt(1, inst_binop("x", binop_add, "x", "x")).
stmt(2, inst_binop("x", binop_add, "x", "x")).
stmt(3, inst_binop("x", binop_add, "x", "x")).
stmt(4, inst_binop("x", binop_add, "x", "x")).
stmt(5, inst_binop("x", binop_add, "x", "x")).
stmt(6, inst_binop("x", binop_add, "x", "x")).
stmt(7, inst_binop("x", binop_add, "x", "x")).
stmt(8, inst_binop("x", binop_add, "x", "x")).
stmt(9, inst_binop("x", binop_add, "x", "x")).
stmt(10, inst_binop("x", binop_add, "x", "x")).
stmt(11, inst_fail).
fall_thru_succ(0, 1).
fall_thru_succ(1, 2).
fall_thru_succ(2, 3).
fall_thru_succ(3, 4).
fall_thru_succ(4, 5).
fall_thru_succ(5, 6).
fall_thru_succ(6, 7).
fall_thru_succ(7, 8).
fall_thru_succ(8, 9).
fall_thru_succ(9, 10).
fall_thru_succ(10, 11).
start(0, [("x", vc(1))]).
*)

(* example 16

  if (x == y) {
    x = x + x;
    x = x + x;
  } else {
    y = y + y;
  }
  fail();

*)

(*
stmt(0, inst_jmp(cond_ne, "x", "y", 3)).
stmt(1, inst_binop("x", binop_add, "x", "x")).
stmt(2, inst_binop("x", binop_add, "x", "x")).
stmt(3, inst_binop("y", binop_add, "y", "y")).
stmt(4, inst_fail).
fall_thru_succ(0, 1).
fall_thru_succ(1, 2).
fall_thru_succ(2, 4).
fall_thru_succ(3, 4).
start(0, [("x", vs("x")), ("y", vs("y"))]).
*)

(* example 17 

    x0 = mksymb();
    y = 42;
    if (x0 != y) {
      x0 = x0;
      x0 = x0;
      x0 = x0;
    } else {
      fail();
    }
*)

(*
stmt(0, inst_jmp(cond_eq, "x", "y", 1)).
stmt(1, inst_fail).
stmt(2, inst_assign("x", "x")).
stmt(3, inst_assign("x", "x")).
stmt(4, inst_assign("x", "x")).
fall_thru_succ(0, 2).
fall_thru_succ(2, 3).
fall_thru_succ(3, 4).
start(0, [("x", vs("x")), ("y", vc(42))]).
*)

(* example 18

    x = mksymb();
    y = mksymb();
    z = mksymb();
    0: if (x != 0)
    1:  x = x; 
    2: if (y != 0)
    3:  y = y;
    4: if (z != 0)
    5:  z = z;
    6: fail();
*)

stmt(0, inst_jmp(cond_eq, "x", "0", 2)).
stmt(1, inst_assign("x", "x")).
stmt(2, inst_jmp(cond_eq, "y", "0", 4)).
stmt(3, inst_assign("y", "y")).
stmt(4, inst_jmp(cond_eq, "z", "0", 6)).
stmt(5, inst_assign("z", "z")).
stmt(6, inst_fail).
fall_thru_succ(0, 1).
fall_thru_succ(1, 2).
fall_thru_succ(2, 3).
fall_thru_succ(3, 4).
fall_thru_succ(4, 5).
fall_thru_succ(5, 6).
start(0, [("x", vs("x")), ("y", vs("y")), ("z", vs("z")), ("0", vc(0))]).


================================================
FILE: examples/tutorial.flg
================================================
(***

This is the full code listing for the Formulog tutorial, which is available at
<https://harvardpl.github.io/formulog/tutorial/>.

***)

(*******************************************************************************
DEFINITIONS
*******************************************************************************)

(* An algebraic data type with two variants *)
type basic_typ =
    | b_int
    | b_bool

(* A type alias *)
type var = string

(* Interpreted operations: for simplicity, we'll support just a few *)
type op =
    | o_add
    | o_eq

type pred =
    | p_var(var)
    | p_bool(bool)
    (* i32 is the type of a 32-bit signed integer *)
    | p_int(i32)
    | p_interp_op(op, pred, pred)
    | p_conj(pred, pred)
    | p_disj(pred, pred)
    | p_neg(pred)
    | p_ite(pred, pred, pred)

type constraint =
    | c_pred(pred)
    | c_conj(constraint, constraint)
    | c_imp(var, basic_typ, pred, constraint)

type typ =
    | t_refined(basic_typ, var, pred)
    | t_func(var, typ, typ)

type kind =
    | k_base
    | k_star

(* Tuples and lists are built-in types *)
type env = (var * typ) list

type expr =
    | e_int(i32)
    | e_var(var)
    | e_let(var, expr, expr)
    | e_lambda(var, expr)
    | e_app(expr, var)
    | e_annot(expr, typ)

(*******************************************************************************
WELL-FORMEDNESS
*******************************************************************************)

rel wf(env, typ, kind)

wf(G, T, k_star) :- wf(G, T, k_base).

wf(G, t_func(X, S, T), k_star) :-
    wf(G, S, _Ks),
    wf((X, S) :: G, T, _Kt).

rel pred_wf(env, pred, basic_typ)

pred_wf(_G, p_bool(_B), b_bool).

pred_wf(_G, p_int(_I), b_int).

pred_wf(G, p_interp_op(o_add, P1, P2), b_int) :-
    pred_wf(G, P1, b_int),
    pred_wf(G, P2, b_int).

pred_wf(G, p_interp_op(o_eq, P1, P2), b_bool) :-
    pred_wf(G, P1, T),
    pred_wf(G, P2, T).

(* We can define a Horn clause with two heads, meaning both conclusions hold *)
pred_wf(G, p_conj(P1, P2), b_bool),
pred_wf(G, p_disj(P1, P2), b_bool) :-
    pred_wf(G, P1, b_bool),
    pred_wf(G, P2, b_bool).

pred_wf(G, p_neg(P), b_bool) :-
    pred_wf(G, P, b_bool).

pred_wf(G, p_ite(P1, P2, P3), T) :-
    pred_wf(G, P1, b_bool),
    pred_wf(G, P2, T),
    pred_wf(G, P3, T).

fun lookup(x: var, g: env): typ option =
    match g with
    | [] => none
    | (y, t) :: rest => if x = y then some(t) else lookup(x, rest)
    end

pred_wf(G, p_var(V), B) :-
    lookup(V, G) = some(t_refined(B, _, _)).

wf(G, t_refined(B, V, P), k_base) :-
    K = (V, t_refined(B, V, p_bool(true))),
    pred_wf(K :: G, P, b_bool).

(*******************************************************************************
CONVERTING CONSTRAINTS AND PREDICATES TO SMT
*******************************************************************************)

type val =
    | v_int(int)
    | v_bool(bool)

fun pred2smt(p: pred): val smt =
    match p with
    | p_bool(b) => `v_bool(b)`
    | p_conj(p1, p2) =>
        let v1 = pred2smt(p1) in
        let v2 = pred2smt(p2) in
        `v_bool(#v_bool_1(v1) /\ #v_bool_1(v2))`
    | p_disj(p1, p2) =>
        let v1 = pred2smt(p1) in
        let v2 = pred2smt(p2) in
        `v_bool(#v_bool_1(v1) \/ #v_bool_1(v2))`
    | p_neg(p1) =>
        let v1 = pred2smt(p1) in
        `v_bool(~#v_bool_1(v1))`
    | p_int(n) => `v_int(int_const(n))`
    | p_interp_op(o, p1, p2) =>
        let v1 = pred2smt(p1) in
        let v2 = pred2smt(p2) in
        match o with
        | o_eq => `v_bool(v1 #= v2)`
        | o_add => `v_int(int_add(#v_int_1(v1), #v_int_1(v2)))`
        end
    | p_ite(p1, p2, p3) =>
        let v1 = pred2smt(p1) in
        let v2 = pred2smt(p2) in
        let v3 = pred2smt(p3) in
        `#if #v_bool_1(v1) then v2 else v3`
    | p_var(x) => `#{x}[val]`
    end

fun constraint2smt(c: constraint): bool smt =
    match c with
    | c_conj(c1, c2) =>
        let s1 = constraint2smt(c1) in
        let s2 = constraint2smt(c2) in
        `s1 /\ s2`
    | c_pred(p) => let s = pred2smt(p) in `#v_bool_1(s)`
    | c_imp(x, _b, p1, c1) =>
        (* Note that we do not actually need to use the basic type `_b` *)
        let prem = pred2smt(p1) in
        let conl = constraint2smt(c1) in
        (* This uses more special syntax for SMT formulas *)
        `forall #{x}[val]. #v_bool_1(prem) ==> conl`
    end

(*******************************************************************************
ENTAILMENT AND SUBTYPING
*******************************************************************************)

fun subst_pred(p: pred, y: var, z: var): pred =
    match p with
    | p_bool(_) | p_int(_) => p
    | p_var(x) => p_var(if x = y then z else x)
    | p_interp_op(o, p1, p2) =>
        let p1 = subst_pred(p1, y, z) in
        let p2 = subst_pred(p2, y, z) in
        p_interp_op(o, p1, p2)
    | p_disj(p1, p2) =>
        let p1 = subst_pred(p1, y, z) in
        let p2 = subst_pred(p2, y, z) in
        p_disj(p1, p2)
    | p_conj(p1, p2) =>
        let p1 = subst_pred(p1, y, z) in
        let p2 = subst_pred(p2, y, z) in
        p_conj(p1, p2)
    | p_neg(p1) => 
        let p1 = subst_pred(p1, y, z) in
        p_neg(p1)
    | p_ite(p1, p2, p3) =>
        let p1 = subst_pred(p1, y, z) in
        let p2 = subst_pred(p2, y, z) in
        let p3 = subst_pred(p3, y, z) in
        p_ite(p1, p2, p3)
    end

rel ent(env, constraint)

ent([], C) :- is_valid(constraint2smt(C)).

fun appears(x: var, p: pred): bool =
    match p with
    | p_var(y) => x = y
    | p_bool(_) | p_int(_) => false
    | p_interp_op(_, p1, p2)
    | p_conj(p1, p2)
    | p_disj(p1, p2) =>
        appears(x, p1) || appears(x, p2)
    | p_neg(p1) => appears(x, p1)
    | p_ite(p1, p2, p3) =>
        appears(x, p1) || appears(x, p2) || appears(x, p3)
    end

ent((X, t_refined(B, Y, P)) :: G, C) :-
    X != Y && !appears(X, P),
    ent(G, c_imp(X, B, subst_pred(P, Y, X), C)).

ent((X, t_refined(B, Y, P)) :: G, C) :-
    X = Y || !appears(X, P),
    ent(G, c_imp(X, B, subst_pred(P, Y, X), C)).

ent((X, t_refined(B, X, P)) :: G, C) :-
    ent(G, c_imp(X, B, P, C)).

fun is_free(x: var, c: constraint): bool =
    match c with
    | c_pred(p) => appears(x, p)
    | c_conj(c1, c2) => is_free(x, c1) || is_free(x, c2)
    | c_imp(y, _, p, c1) =>
        x != y && (appears(x, p) || is_free(x, c1))
    end

ent((X, t_func(_, _, _)) :: G, C) :-
    !is_free(X, C),
    ent(G, C).

fun subst_typ(t: typ, y: var, z: var): typ =
    match t with
    | t_refined(b, v, p) =>
        if v = y then t else t_refined(b, v, subst_pred(p, y, z)) 
    | t_func(x, s, t) =>
        let s = subst_typ(s, y, z) in
        let t = if x = y then t else subst_typ(t, y, z) in
        t_func(x, s, t)
    end

rel sub(env, typ, typ)

sub(G, t_refined(B, V1, P1), t_refined(B, V2, P2)) :-
    ent(G, c_imp(V1, B, P1, c_pred(subst_pred(P2, V2, V1)))).

sub(G, t_func(X1, S1, T1), t_func(X2, S2, T2)) :-
    sub(G, S2, S1),
    sub((X2, S2) :: G, subst_typ(T1, X1, X2), T2).

(*******************************************************************************
TYPE SYNTHESIS
*******************************************************************************)

rel syn(env, expr, typ)

(* Declare relation for type checking, so we can refer to it *)
rel chk(env, expr, typ)

syn(G, e_var(X), T) :- lookup(X, G) = some(T).

(* Here we give an int n the type int{v : v = n} *)
syn(_G, e_int(N), t_refined(b_int, "v", P)) :-
    P = p_interp_op(o_eq, p_var("v"), p_int(N)).

syn(G, e_annot(E, T), T) :-
    wf(G, T, _k),
    chk(G, E, T).

syn(G, e_app(E, Y), subst_typ(T, X, Y)) :-
    syn(G, E, t_func(X, S, T)),
    chk(G, e_var(Y), S).

(*******************************************************************************
TYPE CHECKING
*******************************************************************************)

chk(G, E, T) :-
    syn(G, E, S),
    sub(G, S, T).

chk(G, e_lambda(X, E), t_func(X, T1, T2)) :-
    chk((X, T1) :: G, E, T2).

chk(G, e_let(X, E1, E2), T2) :-
    syn(G, E1, T1),
    chk((X, T1) :: G, E2, T2).

(*******************************************************************************
RUNNING SOME EXAMPLES
*******************************************************************************)

rel ex(i32, env, expr, typ)
rel check_ex(i32)

check_ex(N) :-
    ex(N, G, E, T),
    chk(G, E, T).

:- check_ex(_).

fun lit_typ(n: i32): typ =
    t_refined(b_int, "v", p_interp_op(o_eq, p_var("v"), p_int(n)))

(*
    Expr
        42
    Type
        int{v: v = 42}
*)
ex(0, [], e_int(42), lit_typ(42)).

(*
    Expr
        43
    Type
        int{v: v = 43}
*)
ex(1, [], e_int(42), lit_typ(43)).

(*
    Expr
        let z = 42 in z
    Type
        int{v: v = 42}
*)
ex(2, [], E, T) :-
    E = e_let("z", e_int(42), e_var("z")),
    T = lit_typ(42).

(*
    Expr
        let y = 0 in
        let x = 42 in x
    Type
        int{v: v = 42}
*)
ex(3, [], E, T) :-
    E1 = e_let("x", e_int(42), e_var("x")),
    E = e_let("y", e_int(0), E1),
    T = lit_typ(42).

(*
    Expr
        let x = 0 in
        let x = 42 in x
    Type
        int{v: v = 42}
*)
ex(4, [], E, T) :-
    E1 = e_let("x", e_int(42), e_var("x")),
    E = e_let("x", e_int(0), E1),
    T = lit_typ(42).

(*
    Expr
        \y. 0 
    Type
        y:int{y: true} -> int{v: v = 0} 
*)
ex(5, [], e_lambda("y", e_int(0)), t_func("y", t_refined(b_int, "y", p_bool(true)), lit_typ(0))).

(*
    Expr
        let z = \y. 0 in
        let x = 42 in
        x
    Type
        int{v: v = 42}
*)
ex(6, [], E, T) :-
    Lam_type = t_func("y", t_refined(b_int, "y", p_bool(true)), lit_typ(0)),
    E1 = e_let("x", e_int(42), e_var("x")),
    E = e_let("z", e_annot(e_lambda("y", e_int(0)), Lam_type), E1),
    T = lit_typ(42).

(*
    Expr
        let z = \y. 0 in
        let x = 42 in
        z x
    Type
        int{v: v = 0}
*)
ex(7, [], E, T) :-
    Lam_type = t_func("y", t_refined(b_int, "y", p_bool(true)), lit_typ(0)),
    E1 = e_let("x", e_int(42), e_app(e_var("z"), "x")),
    E = e_let("z", e_annot(e_lambda("y", e_int(0)), Lam_type), E1),
    T = lit_typ(0).

(* The type of the add function *)
const add_typ: typ =
    let add = p_interp_op(o_add, p_var("x"), p_var("y")) in
    let eq = p_interp_op(o_eq, p_var("v"), add) in
    let r = t_refined(b_int, "v", eq) in
    let t = t_func("y", t_refined(b_int, "v", p_bool(true)), r) in
    let s = t_refined(b_int, "v", p_bool(true)) in
    t_func("x", s, t)

(*
    Context
        add |-> x:int{v: true} -> (y:int{v: true} -> int{v: v = x + y})
        one |-> int{v: v = 1}
    Expr
        let z = 41 in
        add z one
    Type
        int{v: v = 42}
*)
ex(8, G, E, T) :-
    G = [("add", add_typ), ("one", lit_typ(1))],
    E = e_let("z", e_int(41), e_app(e_app(e_var("add"), "z"), "one")),
    T = lit_typ(42).

================================================
FILE: license-header
================================================
/*-
 * #%L
 * Formulog
 * %%
 * Copyright (C) $YEAR President and Fellows of Harvard College
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

================================================
FILE: misc/flg.vim
================================================
" Vim syntax file
" Language: Formulog
" Maintainer: Aaron Bembenek
" Latest Revision: 9 May 2019

if exists("b:current_syntax")
    finish
endif

syn match number "\v<[0-9]+(\.[0-9]*)*[lLfFdD]?>"
syn match number "\v<[0-9]*\.[0-9]+[lLfFdD]?>"
syn match keywords ":-"
syn match keywords "\~"
syn match keywords "#="
syn match keywords '::'
syn match keywords "|"
syn match keywords "&"
syn match keywords "+"
syn match keywords "-"
syn match keywords "*"
syn match keywords "/"
syn match keywords "\\"
syn match keywords "!"
syn match keywords "="
syn match keywords "<"
syn match keywords ">"
syn match keywords "\."
syn match keywords "{"
syn match keywords "}"
syn match keywords "<\["
syn match keywords "]>"
syn keyword keywords type rel const match let if then else end fun in with uninterpreted and sort
syn keyword todo contained TODO XXX FIXME
syn region comment start="(\*" end="\*)" fold contains=todo,comment
syn keyword typeKeywords i32 i64 fp32 fp64 list bool option cmp string smt bv fp sym int array
syn match variable "\v<[A-Z][a-zA-Z0-9_]*>"
syn match keywords "#let"
syn match keywords "#if"
syn match annotation "@\v<[a-zA-Z0-9_]+>"
syn match bool "true"
syn match bool "false"
syn region string start=/\v"/ skip=/\v\\./ end=/\v"/
syn region formula start="`" end="`" contains=number,string,keywords,comment,variable,typeKeywords
let b:current_syntax = "flg"

hi def link number          Constant
hi def link string          Constant
hi def link bool            Constant
hi def link keywords        Statement
hi def link comment         Comment 
hi def link typeKeywords    Type
hi def link variable        Identifier 
hi def link todo            Todo 
hi def link annotation      Special
hi def link formula         Special


================================================
FILE: pom.xml
================================================
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>edu.harvard.seas.pl</groupId>
    <artifactId>formulog</artifactId>
    <version>0.8.0-SNAPSHOT</version>
    <name>formulog</name>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
            <version>4.13.2</version>
        </dependency>
        <dependency>
            <groupId>org.jgrapht</groupId>
            <artifactId>jgrapht-core</artifactId>
            <version>1.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4</artifactId>
            <version>4.13.2</version>
        </dependency>
        <dependency>
            <groupId>org.pcollections</groupId>
            <artifactId>pcollections</artifactId>
            <version>5.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.20.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.bcel</groupId>
            <artifactId>bcel</artifactId>
            <version>6.12.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.21.3</version>
        </dependency>
        <dependency>
            <groupId>info.picocli</groupId>
            <artifactId>picocli</artifactId>
            <version>4.7.7</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.antlr</groupId>
                <artifactId>antlr4-maven-plugin</artifactId>
                <version>4.13.2</version>
                <configuration>
                    <visitor>true</visitor>
                </configuration>
                <executions>
                    <execution>
                        <id>antlr</id>
                        <goals>
                            <goal>antlr4</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>edu.harvard.seas.pl.formulog.Main</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>license-maven-plugin</artifactId>
                <version>2.7.1</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.15.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.diffplug.spotless</groupId>
                <artifactId>spotless-maven-plugin</artifactId>
                <version>3.4.0</version>
                <configuration>
                    <java>
                        <googleJavaFormat>
                            <version>1.23.0</version>
                            <style>GOOGLE</style>
                        </googleJavaFormat>
                        <licenseHeader>
                            <file>${project.basedir}/license-header</file>
                        </licenseHeader>
                    </java>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>


================================================
FILE: src/main/antlr4/edu/harvard/seas/pl/formulog/parsing/generated/Formulog.g4
================================================
grammar Formulog;

prog
:
	(
		metadata
		| stmt
	)* EOF
;

tsvFile
:
	tabSeparatedTermLine* EOF
;

tabSeparatedTermLine
:
	(term (TAB term)*)? NEWLINE	
;

// Program metadata ////////////////////////////////////////////////////////////

metadata
:
	topLevelFunDefs '.'? # funDecl
	| annotation* relType = 'rel' ID maybeAnnotatedTypeList '.'? # relDecl
	| 'type' typeDefLHS EQ type '.'? # typeAlias
	| 'type' typeDefLHS EQ typeDefRHS
	(
		'and' typeDefLHS EQ typeDefRHS
	)* '.'? # typeDecl
	| 'uninterpreted' 'fun' constructorType ':' type '.'? # uninterpFunDecl
	| 'uninterpreted' 'sort' typeDefLHS '.'? # uninterpSortDecl
;

maybeAnnotatedTypeList
:
	'(' (var ':')? type (',' (var ':')? type)* ')'
	| // can be empty
;

funDefLHS
:
	ID args = varTypeList ':' retType = type
;

topLevelFunDefs
:
	intro = (FUN | CONST) funDefLHS EQ term
	(
		'and' funDefLHS EQ term
	)*
;

funDefs
:
	FUN funDefLHS EQ term
	(
		'and' funDefLHS EQ term
	)*
;

constructorType
:
	ID typeList
;

var
:
	VAR
	| ID
;

varTypeList
:
	'(' var ':' type
	(
		',' var ':' type
	)* ')'
	| // can be empty
;

typeList
:
	'(' type
	(
		',' type
	)* ')'
	| // can be empty

;

type0
:
	'(' type ')' # parenType
	| TYPEVAR # typeVar
	| type0 ID parameterList # typeRef
	| (
		'(' type
		(
			',' type
		)* ')'
	)? ID parameterList # typeRef
;

type
:
	type0
	(
		'*' type0
	)* # tupleType
;

parameterList
:
	'[' parameter
	(
		',' parameter
	)* ']'
	| // can be empty

;

parameter
:
	'?' # wildCardParam
	| type # typeParam
	| INT # intParam 
;

typeDefLHS
:
	(
		TYPEVAR
		| '(' TYPEVAR
		(
			',' TYPEVAR
		)* ')'
	)? ID
;

typeDefRHS
:
	adtDef
	| recordDef
;

adtDef
:
	'|'? constructorType
	(
		'|' constructorType
	)*
	| // can be empty

;

recordDef
:
	'{' recordEntryDef
	(
		';' recordEntryDef
	)* ';'? '}'
;

recordEntryDef
:
	ID ':' type
;

annotation
:
	'@' ID
;

// Program logic ///////////////////////////////////////////////////////////////

stmt
:
	clause # clauseStmt
	| fact # factStmt
	| query # queryStmt
;

clause
:
	head = nonEmptyTermList ':-' body = nonEmptyTermList '.'
;

fact
:
	term '.'
;

query
:
	':-' term '.'
;

predicate
:
	ID termArgs
;

functor
:
	id =
	(
		ID
		| XID
		| XVAR
	) parameterList termArgs # indexedFunctor
;

termArgs
:
	(
		'('
		(
			term
			(
				',' term
			)*
		) ')'
	)?
;

term
:
	HOLE # holeTerm
	| 'fold' '[' ID ']' termArgs # foldTerm
	| functor # functorTerm
	| list # listTerm
	| tuple # tupleTerm
	| '(' term ')' # parensTerm
	| op =
	(
		MINUS
		| BANG
		| PLUS
	) term # unopTerm
	| term op =
	(
		MUL
		| DIV
		| REM
	) term # binopTerm
	| term op =
	(
		PLUS
		| MINUS
	) term # binopTerm
	| < assoc = right > term '::' term # consTerm
	| term op =
	(
		LT
		| LTE
		| GT
		| GTE
	) term # binopTerm
	| term op =
	(
		EQ
		| NEQ
	) term # binopTerm
	| term op = AMP term # binopTerm
	| term op = CARET term # binopTerm
	| term op = AMPAMP term # binopTerm
	| term op = BARBAR term # binopTerm
	| VAR # varTerm
	| QSTRING # stringTerm
	| val =
	(
		INT
		| HEX
	) # i32Term
	| val = (INTL | HEXL) # i64Term
	| val = FP64 # doubleTerm
	| val = FP32 # floatTerm
	| val =
	(
		FP32_NAN
		| FP32_POS_INFINITY
		| FP32_NEG_INFINITY
		| FP64_NAN
		| FP64_POS_INFINITY
		| FP64_NEG_INFINITY
	) # specialFPTerm
	| '{' recordEntries '}' # recordTerm
	| '{' term 'with' recordEntries '}' # recordUpdateTerm
	| '`' term '`' # formulaTerm
	| '#' '{' term '}' '[' parameter ']' # termSymFormula
	| NOT term # notFormula
	| < assoc = left > term op = FORMULA_EQ term # binopFormula
	| < assoc = right > term op = AND term # binopFormula
	| < assoc = right > term op = OR term # binopFormula
	| < assoc = right > term op = IMP term # binopFormula
	| < assoc = right > term op = IFF term # binopFormula
	| '#let' term EQ term 'in' term # letFormula
	| quantifier =
	(
		FORALL
		| EXISTS
	) variables = nonEmptyTermList
	(
		':' pattern = nonEmptyTermList
	)? '.' boundTerm = term # quantifiedFormula
	| '#if' term 'then' term 'else' term # iteTerm
	| term ISNOT ID # outermostCtor
	| 'match' term 'with' '|'? matchClause
	(
		'|' matchClause
	)* 'end' # matchExpr
	| 'let' lhs = letBind '=' assign = term 'in' body = term # letExpr
	| 'let' funDefs 'in' letFunBody = term # letFunExpr
	| 'if' guard = term 'then' thenExpr = term 'else' elseExpr = term # ifExpr
;

recordEntries
:
	recordEntry
	(
		';' recordEntry
	)* ';'?
;

recordEntry
:
	ID '=' term
;

letBind
:
	(
		term
		| '(' term ',' term
		(
			',' term
		)* ')'
	)
;

nonEmptyTermList
:
	term
	(
		',' term
	)*
;

list
:
	'['
	(
		term
		(
			',' term
		)*
	)? ']'
;

tuple
:
	'(' term ',' term
	(
		',' term
	)* ')'
;

matchClause
:
	pats = patterns '=>' rhs = term
;

patterns
:
	term
	(
		'|' term
	)*
;

// Tokens //////////////////////////////////////////////////////////////////////

AND
:
	'/\\'
;

OR
:
	'\\/'
;

IMP
:
	'==>'
;

IFF
:
	'<==>'
;

NOT
:
	'~'
;

FORMULA_EQ
:
	'#='
;

FP32_NAN
:
	'fp32_nan'
;

FP32_POS_INFINITY
:
	'fp32_pos_infinity'
;

FP32_NEG_INFINITY
:
	'fp32_neg_infinity'
;

FP64_NAN
:
	'fp64_nan'
;

FP64_POS_INFINITY
:
	'fp64_pos_infinity'
;

FP64_NEG_INFINITY
:
	'fp64_neg_infinity'
;

TYPEVAR
:
	'\'' ID
;

XVAR
:
	'#' VAR
;

VAR
:
	[A-Z_] [a-zA-Z0-9_]*
;

INT
:
	[0-9]+
;

INTL
:
	[0-9]+ ('l' | 'L')
;

HEX
:
	'0x' [0-9a-fA-F]+
;

HEXL
:
	'0x' [0-9a-fA-F]+ ('l' | 'L')
;

fragment
FP
:
	INT '.' INT
;

fragment
FPE
:
	(
		FP
		| INT
	)
	(
		'e'
		| 'E'
	) ('+'|'-')? INT
;

FP32
:
	(
		FP
		| INT
		| FPE
	)
	(
		'F'
		| 'f'
	)
;

FP64
:
	(
		FP
		| FPE
	)
	(
		'D'
		| 'd'
	)?
	| INT
	(
		'D'
		| 'd'
	)
;

LT
:
	'<'
;

LTE
:
	'<='
;

GT
:
	'>'
;

GTE
:
	'>='
;

MUL
:
	'*'
;

DIV
:
	'/'
;

REM
:
	'%'
;

PLUS
:
	'+'
;

MINUS
:
	'-'
;

BANG
:
	'!'
;

CARET
:
	'^'
;

AMP
:
	'&'
;

BARBAR
:
	'||'
;

AMPAMP
:
	'&&'
;

ISNOT
:
	'not'
;

EQ
:
	'='
;

NEQ
:
	'!='
;

FORALL
:
	'forall'
;

EXISTS
:
	'exists'
;

FUN
:
	'fun'
;

CONST
:
	'const'
;

HOLE
:
	'??'
;

NEWLINE
:
	('\r\n' | [\n\r]) -> channel(HIDDEN)
;

TAB
:
	'\t' -> channel(HIDDEN)
;

SPACES
:
	[ ]+ -> skip
;

COMMENT
:
	'(*'
	(
		COMMENT
		| .
	)*? '*)' -> skip
;

XID
:
	'#' ID
;

ID
:
	[a-z] [a-zA-Z0-9_]*
;

fragment
ESCAPE
:
	'\\' .
;

QSTRING
:
	'"'
	(
		ESCAPE
		| ~( '\n' | '\r' | '"' | '\\' )
	)* '"'
;

================================================
FILE: src/main/java/edu/harvard/seas/pl/formulog/Configuration.java
================================================
/*-
 * #%L
 * Formulog
 * %%
 * Copyright (C) 2019-2023 President and Fellows of Harvard College
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package edu.harvard.seas.pl.formulog;

import edu.harvard.seas.pl.formulog.ast.Rule;
import edu.harvard.seas.pl.formulog.db.IndexedFactDb;
import edu.harvard.seas.pl.formulog.eval.IndexedRule;
import edu.harvard.seas.pl.formulog.smt.CheckSatAssumingSolver;
import edu.harvard.seas.pl.formulog.smt.PushPopSolver;
import edu.harvard.seas.pl.formulog.smt.SmtLibSolver;
import edu.harvard.seas.pl.formulog.smt.SmtStatus;
import edu.harvard.seas.pl.formulog.smt.SmtStrategy;
import edu.harvard.seas.pl.formulog.symbols.FunctionSymbol;
import edu.harvard.seas.pl.formulog.symbols.RelationSymbol;
import edu.harvard.seas.pl.formulog.util.Dataset;
import edu.harvard.seas.pl.formulog.util.EnumerableThreadLocal;
import edu.harvard.seas.pl.formulog.util.Pair;
import edu.harvard.seas.pl.formulog.util.SharedLong;
import edu.harvard.seas.pl.formulog.util.Util;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public final class Configuration {

  private Configuration() {
    throw new AssertionError("impossible");
  }

  public static final boolean runTests = propIsSet("runTests");
  public static final String testFile = System.getProperty("testFile");

  public static final boolean recordFuncDiagnostics = propIsSet("timeFuncs");
  private static final Map<FunctionSymbol, AtomicLong> funcTimes = new ConcurrentHashMap<>();

  public static final boolean recordRuleDiagnostics = propIsSet("timeRules");
  private static final Map<Rule<?, ?>, Pair<AtomicLong, AtomicLong>> ruleTimes =
      new ConcurrentHashMap<>();

  public static final boolean debugSmt = propIsSet("debugSmt");
  public static final String debugSmtOutDir = getStringProp("debugSmtOutDir", "solver_logs");

  public static final boolean timeSmt = propIsSet("timeSmt");
  public static final boolean smtMemoize = propIsSet("smtMemoize", true);
  private static final Map<SmtLibSolver, Dataset> perProcessSmtEvalStats =
      new ConcurrentHashMap<>();
  private static final Dataset smtEvalStats = new Dataset();
  private static final AtomicLong smtDeclGlobalsTime = new AtomicLong();
  private static final AtomicLong smtEncodeTime = new AtomicLong();
  private static final AtomicLong smtDeclTime = new AtomicLong();
  private static final AtomicLong smtInferTime = new AtomicLong();
  private static final AtomicLong smtSerialTime = new AtomicLong();
  public static final SharedLong smtWaitTime = new SharedLong();
  private static final AtomicInteger smtNumCallsSat = new AtomicInteger();
  private static final AtomicInteger smtNumCallsUnsat = new AtomicInteger();
  private static final AtomicInteger smtNumCallsUnknown = new AtomicInteger();
  private static final AtomicInteger smtNumCallsDoubleCheck = new AtomicInteger();
  private static final AtomicInteger smtNumCallsFalseUnknown = new AtomicInteger();

  // XXX I don't think this is being used any more
  private static final AtomicLong smtTotalTime = new AtomicLong();

  public static void recordSmtTime(long delta) {
    smtTotalTime.addAndGet(delta);
  }

  public static long getSmtTotalTime() {
    return smtTotalTime.get();
  }

  public static final boolean printRelSizes = propIsSet("printRelSizes");
  public static final boolean printFinalRules = propIsSet("printFinalRules");
  public static final boolean simplifyFormulaVars = propIsSet("simplifyFormulaVars", true);
  public static final boolean debugRounds = propIsSet("debugRounds");
  public static final boolean debugParallelism = propIsSet("debugParallelism");

  public static final int optimizationSetting = getIntProp("optimize", 0);

  public static final int taskSize = getIntProp("taskSize", 128);

  public static final int smtTaskSize = getIntProp("smtTaskSize", 8);
  public static final int smtCacheSize = getIntProp("smtCacheSize", 100);
  public static final String smtSolver;

  static {
    smtSolver = getStringProp("smtSolver", "z3");
    switch (smtSolver) {
      case "z3":
      case "cvc4":
      case "yices":
      case "boolector":
        break;
      default:
        throw new IllegalArgumentException("Unrecognized solver: " + smtSolver);
    }
  }

  public static final String smtLogic = getStringProp("smtLogic", "ALL");
  public static final boolean smtDeclareAdts = propIsSet("smtDeclareAdts", true);
  public static final boolean smtCacheHardResets = propIsSet("smtCacheHardResets", false);
  public static final boolean smtUseNegativeLiterals = propIsSet("smtUseNegativeLiterals", false);
  public static final boolean smtDoubleCheckUnknowns = propIsSet("smtDoubleCheckUnknowns", true);
  public static final boolean smtUseSingleShotSolver =
      propIsSet("smtUseSingleShotSolver", false) || smtSolver.equals("boolector");
  public static final boolean smtCheckSuccess = propIsSet("smtCheckSuccess", false);

  private static final Dataset pushPopStackSize = new Dataset();
  private static final Dataset pushPopStackReuse = new Dataset();
  private static final Dataset pushPopStackPushes = new Dataset();
  private static final Dataset pushPopStackPops = new Dataset();
  private static final Dataset pushPopStackDelta = new Dataset();
  private static final Dataset csaCacheHitRate = new Dataset();
  private static final Dataset csaCacheUseRate = new Dataset();
  private static final Dataset csaCacheSize = new Dataset();
  private static final Dataset csaCacheHits = new Dataset();
  private static final Dataset csaCacheMisses = new Dataset();
  private static final AtomicInteger csaCacheClears = new AtomicInteger();
  private static final Dataset csaEvalStats = new Dataset();
  private static final Dataset pushPopEvalStats = new Dataset();
  private static final Dataset otherSolverEvalStats = new Dataset();

  public static final boolean oneRuleAtATime = propIsSet("oneRuleAtATime");
  public static final boolean parallelizeInnerLoops = propIsSet("parallelizeInnerLoops", true);

  public static final boolean useDemandTransformation = propIsSet("useDemandTransformation", true);
  public static final boolean restoreStratification = propIsSet("restoreStratification", true);

  public static final List<String> trackedRelations = getListProp("trackedRelations");

  public static final boolean debugMst = propIsSet("debugMst");
  public static final boolean debugStratification = propIsSet("debugStratification");
  public static final String debugStratificationOutDir =
      getStringProp("debugStratificationOutDir", "stratification_graphs");

  public static final boolean testCodeGen = propIsSet("testCodeGen");
  public static final boolean testCodeGenEager = propIsSet("testCodeGenEager");
  public static final boolean keepCodeGenTestDirs = propIsSet("keepCodeGenTestDirs");
  public static final String cxxCompiler = getStringProp("cxxCompiler", null);

  public static final String souffleInclude = System.getProperty("souffleInclude");
  public static final String boostInclude = System.getProperty("boostInclude");
  public static final String boostLib = System.getProperty("boostLib");
  public static final String tbbInclude = System.getProperty("tbbInclude");
  public static final String tbbLib = System.getProperty("tbbLib");
  public static final String outputExec = System.getProperty("outputExec");

  public static final int memoizeThreshold() {
    return getIntProp("memoizeThreshold", 0);
  }

  public static final boolean genComparators = propIsSet("genComparators", true);
  public static final boolean minIndex = propIsSet("minIndex", true);

  public static final boolean inlineInRules = propIsSet("inlineInRules", true);

  public static final boolean eagerSemiNaive = propIsSet("eagerSemiNaive");
  public static final boolean codegenSplitOnSmt = propIsSet("codegenSplitOnSmt");

  public static final boolean useHashDbFilter = propIsSet("useHashDbFilter");

  public static final boolean recordWork = propIsSet("recordWork");
  public static final boolean recordDetailedWork = propIsSet("recordDetailedWork");
  public static final SharedLong work = new SharedLong();
  public static final SharedLong workItems = new SharedLong();
  public static final SharedLong newDerivs = new SharedLong();
  public static final SharedLong dupDerivs = new SharedLong();
  public static final Map<IndexedRule, SharedLong> workPerRule = new ConcurrentHashMap<>();

  public static class SmtStats {
    public long time;
    public long ncalls;

    public void add(long time) {
      this.time += time;
      ncalls++;
    }
  }

  public static final EnumerableThreadLocal<SmtStats> smtTime =
      new EnumerableThreadLocal<>(SmtStats::new);
  public static final SharedLong smtCacheClears = new SharedLong();
  public static final SharedLong smtCacheHits = new SharedLong();
  public static final SharedLong smtCacheMisses = new SharedLong();

  static {
    if (recordFuncDiagnostics) {
      Runtime.getRuntime()
          .addShutdownHook(
              new Thread() {

                @Override
                public void run() {
                  printFuncDiagnostics(System.err);
                }
              });
    }
    if (recordRuleDiagnostics) {
      Runtime.getRuntime()
          .addShutdownHook(
              new Thread() {

                @Override
                public void run() {
                  printRuleDiagnostics(System.err);
                }
              });
    }
    if (timeSmt) {
      Runtime.getRuntime()
          .addShutdownHook(
              new Thread() {

                @Override
                public void run() {
                  printSmtDiagnostics(System.err);
                }
              });
    }
    Runtime.getRuntime()
        .addShutdownHook(
            new Thread() {

              @Override
              public void run() {
                printConfiguration(System.err);
              }
            });
  }

  public static synchronized void printConfiguration(PrintStream out) {
    // out.println("[CONFIG] noResults=" + noResults);
    // out.println("[CONFIG] timeRules=" + recordRuleDiagnostics);
    // out.println("[CONFIG] timeFuncs=" + recordFuncDiagnostics);
    // out.println("[CONFIG] timeSmt=" + timeSmt);
    // out.println("[CONFIG] optimize=" + optimizationSetting);
    // out.println("[CONFIG] taskSize=" + taskSize);
    // out.println("[CONFIG] smtTaskSize=" + smtTaskSize);
    // out.println("[CONFIG] memoizeThreshold=" + memoizeThreshold());
    // out.println("[CONFIG] noModel=" + noModel());
  }

  public static void recordSmtDeclTime(long time) {
    smtDeclTime.addAndGet(time);
  }

  public static void recordSmtInferTime(long time) {
    smtInferTime.addAndGet(time);
  }

  public static void recordSmtSerialTime(long time) {
    smtSerialTime.addAndGet(time);
  }

  public static void recordSmtEvalTime(
      SmtLibSolver solver, long encodeTime, long evalTime, SmtStatus result) {
    smtEncodeTime.addAndGet(encodeTime);
    smtEvalStats.addDataPoint(evalTime);
    if (solver instanceof CheckSatAssumingSolver) {
      csaEvalStats.addDataPoint(evalTime);
    } else if (solver instanceof PushPopSolver) {
      pushPopEvalStats.addDataPoint(evalTime);
    } else {
      otherSolverEvalStats.addDataPoint(evalTime);
    }
    Util.lookupOrCreate(perProcessSmtEvalStats, solver, () -> new Dataset()).addDataPoint(evalTime);
    switch (result) {
      case SATISFIABLE:
        smtNumCallsSat.incrementAndGet();
        break;
      case UNKNOWN:
        smtNumCallsUnknown.incrementAndGet();
        break;
      case UNSATISFIABLE:
        smtNumCallsUnsat.incrementAndGet();
        break;
    }
  }

  public static void recordSmtWaitTime(long time) {
    smtWaitTime.add(time);
  }

  public static void recordSmtDeclGlobalsTime(long time) {
    smtDeclGlobalsTime.addAndGet(time);
  }

  public static synchronized void printSmtDiagnostics(PrintStream out) {
    Dataset callsPerSolver = new Dataset();
    Dataset timePerSolver = new Dataset();
    for (Dataset ds : perProcessSmtEvalStats.values()) {
      callsPerSolver.addDataPoint(ds.size());
      timePerSolver.addDataPoint(ds.computeSum());
    }
    out.println("[SMT WAIT TIME] " + smtWaitTime.unsafeGet() / 1e6 + "ms");
    out.println("[SMT DECL GLOBALS TIME] " + smtDeclGlobalsTime.get() / 1e6 + "ms");
    out.println("[SMT ENCODE TIME - TOTAL] " + smtEncodeTime.get() / 1e6 + "ms");
    out.println("[SMT ENCODE TIME - DECL] " + smtDeclTime.get() / 1e6 + "ms");
    out.println("[SMT ENCODE TIME - INFER] " + smtInferTime.get() / 1e6 + "ms");
    out.println("[SMT ENCODE TIME - SERIAL] " + smtSerialTime.get() / 1e6 + "ms");
    out.printf("[SMT EVAL TIME] %1.1fms%n", smtEvalStats.computeSum() / 1e6);
    out.println("[SMT EVAL TIME PER CALL (ms)] " + smtEvalStats.getStatsString(1e-6));
    out.println("[SMT EVAL TIME PER SOLVER (ms)] " + timePerSolver.getStatsString(1e-6));
    out.println("[SMT NUM CALLS PER SOLVER] " + callsPerSolver.getStatsString());
    out.println("[SMT NUM CALLS - SAT] " + smtNumCallsSat);
    out.println("[SMT NUM CALLS - UNSAT] " + smtNumCallsUnsat);
    out.println("[SMT NUM CALLS - UNKNOWN] " + smtNumCallsUnknown);
    out.println("[SMT NUM CALLS - DOUBLE CHECK] " + smtNumCallsDoubleCheck);
    out.println("[SMT NUM CALLS - FALSE UNKNOWN] " + smtNumCallsFalseUnknown);
    if (csaEvalStats.size() > 0) {
      out.println("--- CSA ---");
      out.printf("[CSA EVAL TIME] %1.1fms%n", csaEvalStats.computeSum() / 1e6);
      out.println("[CSA EVAL TIME PER CALL (ms)] " + csaEvalStats.getStatsString(1e-6));
      out.println("[CSA CACHE LIMIT] " + smtCacheSize);
      out.println("[CSA CACHE BASE SIZE] " + csaCacheSize.getStatsString());
      out.println("[CSA CACHE HITS] " + csaCacheHits.getStatsString());
      out.println("[CSA CACHE MISSES] " + csaCacheMisses.getStatsString());
      out.println("[CSA CACHE HIT RATE] " + csaCacheHitRate.getStatsString());
      out.println("[CSA CACHE USE RATE] " + csaCacheUseRate.getStatsString());
      out.println("[CSA CACHE CLEARS] " + csaCacheClears.get());
    }
    if (pushPopEvalStats.size() > 0) {
      out.println("--- PUSH POP ---");
      out.printf("[PUSH POP EVAL TIME] %1.1fms%n", pushPopEvalStats.computeSum() / 1e6);
      out.println("[PUSH POP EVAL TIME PER CALL (ms)] " + pushPopEvalStats.getStatsString(1e-6));
      out.println("[PUSH POP STACK BASE SIZE] " + pushPopStackSize.getStatsString());
      out.println("[PUSH POP STACK PUSHES] " + pushPopStackPushes.getStatsString());
      out.println("[PUSH POP STACK POPS] " + pushPopStackPops.getStatsString());
      out.println("[PUSH POP STACK DELTA] " + pushPopStackDelta.getStatsString());
      out.println("[PUSH POP STACK REUSE] " + pushPopStackReuse.getStatsString());
    }
    if (otherSolverEvalStats.size() > 0) {
      out.println("--- OTHER ---");
      out.printf("[OTHER EVAL TIME] %1.1fms%n", otherSolverEvalStats.computeSum() / 1e6);
      out.println("[OTHER EVAL TIME PER CALL (ms)] " + otherSolverEvalStats.getStatsString(1e-6));
    }
  }

  public static void recordPushPopSolverStats(
      int solverId, int stackStartSize, int pops, int pushes) {
    pushPopStackSize.addDataPoint(stackStartSize);
    pushPopStackReuse.addDataPoint(stackStartSize - pops);
    pushPopStackPops.addDataPoint(pops);
    pushPopStackPushes.addDataPoint(pushes);
    pushPopStackDelta.addDataPoint(pushes - pops);
  }

  public static void recordCsaCacheStats(int solverId, int hits, int misses, int oldSize) {
    int numAsserts = hits + misses;
    csaCacheHits.addDataPoint(hits);
    csaCacheMisses.addDataPoint(misses);
    csaCacheHitRate.addDataPoint(numAsserts == 0 ? 1 : (double) hits / numAsserts);
    csaCacheUseRate.addDataPoint(oldSize == 0 ? 1 : (double) hits / oldSize);
    csaCacheSize.addDataPoint(oldSize);
  }

  public static void recordSmtDoubleCheck(boolean falseUnknown) {
    smtNumCallsDoubleCheck.incrementAndGet();
    if (falseUnknown) {
      smtNumCallsFalseUnknown.incrementAndGet();
    }
  }

  public static void recordCsaCacheClear(int solverId) {
    csaCacheClears.incrementAndGet();
  }

  public static void recordFuncTime(FunctionSymbol func, long time) {
    AtomicLong l = Util.lookupOrCreate(funcTimes, func, () -> new AtomicLong());
    l.addAndGet(time);
  }

  public static Map<FunctionSymbol, AtomicLong> getFuncDiagnostics() {
    return Collections.unmodifiableMap(funcTimes);
  }

  public static synchronized void printFuncDiagnostics(PrintStream out) {
    Map<FunctionSymbol, AtomicLong> times = Configuration.getFuncDiagnostics();
    List<Map.Entry<FunctionSymbol, AtomicLong>> sorted =
        times.entrySet().stream().sorted(sortTimes).collect(Collectors.toList());
    Iterator<Map.Entry<FunctionSymbol, AtomicLong>> it = sorted.iterator();
    int end = Math.min(times.size(), 10);
    for (int i = 0; i < end; ++i) {
      Map.Entry<FunctionSymbol, AtomicLong> e = it.next();
      out.println("[FUNC DIAGNOSTICS] " + e.getValue().get() + "ms: " + e.getKey());
    }
  }

  private static final Comparator<Map.Entry<?, AtomicLong>> sortTimes =
      new Comparator<Map.Entry<?, AtomicLong>>() {

        @Override
        public int compare(Entry<?, AtomicLong> e1, Entry<?, AtomicLong> e2) {
          return -Long.compare(e1.getValue().get(), e2.getValue().get());
        }
      };

  private static final Comparator<Map.Entry<?, Pair<AtomicLong, AtomicLong>>> sortPairedTimes =
      new Comparator<Map.Entry<?, Pair<AtomicLong, AtomicLong>>>() {

        @Override
        public int compare(
            Entry<?, Pair<AtomicLong, AtomicLong>> e1, Entry<?, Pair<AtomicLong, AtomicLong>> e2) {
          return -Long.compare(getTotal(e1), getTotal(e2));
        }

        private long getTotal(Entry<?, Pair<AtomicLong, AtomicLong>> e) {
          Pair<AtomicLong, AtomicLong> p = e.getValue();
          return p.fst().get() + p.snd().get();
        }
      };

  public static void recordRulePrefixTime(Rule<?, ?> rule, long time) {
    Pair<AtomicLong, AtomicLong> p =
        Util.lookupOrCreate(ruleTimes, rule, () -> new Pair<>(new AtomicLong(), new AtomicLong()));
    p.fst().addAndGet(time);
  }

  public static void recordRuleSuffixTime(Rule<?, ?> rule, long time) {
    Pair<AtomicLong, AtomicLong> p =
        Util.lookupOrCreate(ruleTimes, rule, () -> new Pair<>(new AtomicLong(), new AtomicLong()));
    p.snd().addAndGet(time);
  }

  public static synchronized void printRuleDiagnostics(PrintStream out) {
    Map<Rule<?, ?>, Pair<AtomicLong, AtomicLong>> times = ruleTimes;
    List<Map.Entry<Rule<?, ?>, Pair<AtomicLong, AtomicLong>>> sorted =
        times.entrySet().stream().sorted(sortPairedTimes).collect(Collectors.toList());
    Iterator<Map.Entry<Rule<?, ?>, Pair<AtomicLong, AtomicLong>>> it = sorted.iterator();
    int end = Math.min(times.size(), 10);
    for (int i = 0; i < end; ++i) {
      Map.Entry<Rule<?, ?>, Pair<AtomicLong, AtomicLong>> e = it.next();
      Pair<AtomicLong, AtomicLong> p = e.getValue();
      long pre = p.fst().get();
      long suf = p.snd().get();
      long total = pre + suf;
      out.println(
          "[RULE DIAGNOSTICS] " + total + " (" + pre + " + " + suf + ") ms:\n" + e.getKey());
    }
  }

  public static synchronized void printRelSizes(
      PrintStream out, String header, IndexedFactDb db, boolean printEmpty) {
    for (RelationSymbol sym : db.getSymbols()) {
      if (printEmpty || !db.isEmpty(sym)) {
        out.println(
            "["
                + header
                + "] "
                + sym
                + ": "
                + db.countDistinct(sym)
                + " / "
                + db.numIndices(sym)
                + " / "
                + db.countDuplicates(sym));
      }
    }
  }

  private static boolean propIsSet(String prop, boolean defaultValue) {
    String val = System.getProperty(prop);
    if (val == null) {
      return defaultValue;
    }
    if (val.equals("true") || val.equals("")) {
      return true;
    }
    if (val.equals("false")) {
      return false;
    }
    throw new IllegalArgumentException("Unexpected argument for property " + prop + ": " + val);
  }

  private static boolean propIsSet(String prop) {
    return propIsSet(prop, false);
  }

  static int getIntProp(String prop, int def) {
    String val = System.getProperty(prop);
    if (val == null) {
      return def;
    }
    try {
      return Integer.parseInt(val);
    } catch (NumberFormatException e) {
      throw new IllegalArgumentException("Property " + prop + " expects an integer argument");
    }
  }

  private static String getStringProp(String prop, String def) {
    String val = System.getProperty(prop);
    if (val == null) {
      return def;
    }
    return val;
  }

  static List<String> getListProp(String prop) {
    String val = System.getProperty(prop);
    if (val == null || val.equals("")) {
      return Collections.emptyList();
    }
    List<String> l = new ArrayList<>();
    breakIntoCollection(val, l);
    return Collections.unmodifiableList(l);
  }

  private static void breakIntoCollection(String s, Collection<String> acc) {
    int split;
    while ((split = s.indexOf(',')) != -1) {
      String sub = s.substring(0, split);
      acc.add(sub);
      if (split == s.length()) {
        return;
      }
      s = s.substring(split + 1);
    }
    acc.add(s);
  }

  static SmtStrategy getSmtStrategy() {
    String val = System.getProperty("smtStrategy");
    if (val == null) {
      val = "queue-1";
    }

    switch (val) {
      case "naive":
        return new SmtStrategy(SmtStrategy.Tag.NAIVE, null);
      case "pushPop":
        return new SmtStrategy(SmtStrategy.Tag.PUSH_POP, null);
      case "pushPopNaive":
        return new SmtStrategy(SmtStrategy.Tag.PUSH_POP_NAIVE, null);
      case "perThreadNaive":
        return new SmtStrategy(SmtStrategy.Tag.PER_THREAD_NAIVE, null);
      case "perThreadPushPop":
        return new SmtStrategy(SmtStrategy.Tag.PER_THREAD_PUSH_POP, null);
      case "perThreadPushPopNaive":
        return new SmtStrategy(SmtStrategy.Tag.PER_THREAD_PUSH_POP_NAIVE, null);
    }

    Pattern p = Pattern.compile("queue-(\\d+)");
    Matcher m = p.matcher(val);
    if (m.matches()) {
      int size = Integer.parseInt(m.group(1));
      return new SmtStrategy(SmtStrategy.Tag.QUEUE, size);
    }
    p = Pattern.compile("bestMatch-(\\d+)");
    m = p.matcher(val);
    if (m.matches()) {
      int size = Integer.parseInt(m.group(1));
      return new SmtStrategy(SmtStrategy.Tag.BEST_MATCH, size);
    }
    p = Pattern.compile("perThreadQueue-(\\d+)");
    m = p.matcher(val);
    if (m.matches()) {
      int size = Integer.parseInt(m.group(1));
      return new SmtStrategy(SmtStrategy.Tag.PER_THREAD_QUEUE, size);
    }
    p = Pattern.compile("perThreadBestMatch-(\\d+)");
    m = p.matcher(val);
    if (m.matches()) {
      int size = Integer.parseInt(m.group(1));
      return new SmtStrategy(SmtStrategy.Tag.PER_THREAD_BEST_MATCH, size);
    }
    throw new IllegalArgumentException("Unrecognized SMT strategy: " + val);
  }
}


================================================
FILE: src/main/java/edu/harvard/seas/pl/formulog/FormulogTester.java
================================================
/*-
 * #%L
 * Formulog
 * %%
 * Copyright (C) 2021-2023 President and Fellows of Harvard College
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package edu.harvard.seas.pl.formulog;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.harvard.seas.pl.formulog.ast.Term;
import edu.harvard.seas.pl.formulog.eval.Evaluation;
import edu.harvard.seas.pl.formulog.eval.EvaluationException;
import edu.harvard.seas.pl.formulog.eval.EvaluationResult;
import edu.harvard.seas.pl.formulog.eval.SemiNaiveEvaluation;
import edu.harvard.seas.pl.formulog.functions.DummyFunctionDef;
import edu.harvard.seas.pl.formulog.functions.FunctionDef;
import edu.harvard.seas.pl.formulog.parsing.ParseException;
import edu.harvard.seas.pl.formulog.parsing.Parser;
import edu.harvard.seas.pl.formulog.symbols.FunctionSymbol;
import edu.harvard.seas.pl.formulog.symbols.RelationSymbol;
import edu.harvard.seas.pl.formulog.symbols.Symbol;
import edu.harvard.seas.pl.formulog.symbols.SymbolManager;
import edu.harvard.seas.pl.formulog.types.TypeChecker;
import edu.harvard.seas.pl.formulog.types.TypeException;
import edu.harvard.seas.pl.formulog.types.WellTypedProgram;
import edu.harvard.seas.pl.formulog.util.sexp.SExp;
import edu.harvard.seas.pl.formulog.util.sexp.SExpException;
import edu.harvard.seas.pl.formulog.util.sexp.SExpParser;
import edu.harvard.seas.pl.formulog.validating.InvalidProgramException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

public class FormulogTester {

  private boolean initialized;
  private final List<FormulogTest> tests = new ArrayList<>();
  private WellTypedProgram prog;

  public synchronized void setup(Reader program, File testFile)
      throws ParseException, TypeException, IOException {
    Parser parser = new Parser();
    prog = new TypeChecker(parser.parse(program)).typeCheck();
    loadTests(testFile, parser);
    initialized = true;
  }

  private void loadTests(File testFile, Parser parser) throws IOException, ParseException {
    tests.clear();
    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode topLevel = objectMapper.readValue(testFile, JsonNode.class);
    Path rootTestDir = testFile.getParentFile().toPath();
    for (JsonNode test : topLevel) {
      tests.add(loadTest(test, rootTestDir, parser));
    }
  }

  private FormulogTest loadTest(JsonNode test, Path rootTestDir, Parser parser)
      throws ParseException, FileNotFoundException {
    String name = test.get("name").asText();
    Path dir = rootTestDir.resolve(name);
    Map<RelationSymbol, Set<Term[]>> m = new HashMap<>();
    for (RelationSymbol sym : prog.getFactSymbols()) {
      if (sym.isEdbSymbol()) {
        FileReader fr = new FileReader(dir.resolve(sym + ".tsv").toFile());
        Set<Term[]> s = parser.parseFacts(sym, fr);
        m.put(sym, s);
      }
    }
    try {
      Function<EvaluationResult, List<String>> logic = parseBoolLogic(test.get("spec").asText());
      return new FormulogTest(name, m, logic);
    } catch (ParseException e) {
      throw new ParseException(-1, "Trouble parsing spec for test " + name + ": " + e.getMessage());
    }
  }

  private Function<EvaluationResult, List<String>> parseBoolLogic(String s) throws ParseException {
    Reader r = new StringReader(s);
    SExpParser p = new SExpParser(r);
    SExp sexp;
    try {
      sexp = p.parse();
    } catch (SExpException e) {
      throw new ParseException(-1, e.getMessage());
    }
    return parseBoolLogic(sexp);
  }

  private Function<EvaluationResult, List<String>> parseBoolLogic(SExp sexp) throws ParseException {
    if (sexp.isAtom()) {
      return parseBoolAtom(sexp.asAtom());
    } else {
      return parseBoolList(sexp.asList());
    }
  }

  private Function<EvaluationResult, List<String>> parseBoolAtom(String atom)
      throws ParseException {
    switch (atom) {
      case "true":
        return r -> Collections.emptyList();
      default:
        throw new ParseException(-1, "Unrecognized boolean constant: " + atom);
    }
  }

  private Function<EvaluationResult, List<String>> parseBoolList(List<SExp> l)
      throws ParseException {
    if (l.isEmpty()) {
      throw new ParseException(-1, "Unexpected empty list");
    }
    SExp head = l.get(0);
    if (head.isList()) {
      throw new ParseException(-1, "Expected an operator, but got a list: " + head);
    }
    String cmd = head.asAtom();
    switch (cmd) {
      case "=":
        {
          if (l.size() != 3) {
            throw new ParseException(-1, "Wrong number of arguments for = operator: " + l.size());
          }
          SExp sexp1 = l.get(1);
          SExp sexp2 = l.get(2);
          Function<EvaluationResult, Integer> f1 = parseIntLogic(sexp1);
          Function<EvaluationResult, Integer> f2 = parseIntLogic(sexp2);
          return r -> {
            int v1 = f1.apply(r);
            int v2 = f2.apply(r);
            if (v1 == v2) {
              return Collections.emptyList();
            } else {
              return Collections.singletonList(
                  "Failed equality: (= "
                      + sexp1
                      + " "
                      + sexp2
                      + ") reduces to (= "
                      + v1
                      + " "
                      + v2
                      + ")");
            }
          };
        }
      case "and":
        {
          List<Function<EvaluationResult, List<String>>> fs = new ArrayList<>();
          for (Iterator<SExp> it = l.listIterator(1); it.hasNext(); ) {
            fs.add(parseBoolLogic(it.next()));
          }
          return r -> {
            List<String> errors = new ArrayList<>();
            for (Function<EvaluationResult, List<String>> f : fs) {
              errors.addAll(f.apply(r));
            }
            return errors;
          };
        }
      default:
        throw new ParseException(-1, "Unrecognized boolean operator: " + cmd);
    }
  }

  private Function<EvaluationResult, Integer> parseIntLogic(SExp sexp) throws ParseException {
    if (sexp.isAtom()) {
      return parseIntAtom(sexp.asAtom());
    } else {
      return parseIntList(sexp.asList());
    }
  }

  private Function<EvaluationResult, Integer> parseIntAtom(String s) throws ParseException {
    try {
      int n = Integer.parseInt(s);
      return r -> n;
    } catch (NumberFormatException e) {
      throw new ParseException(-1, "Expected an integer constant but got " + s);
    }
  }

  private Function<EvaluationResult, Integer> parseIntList(List<SExp> l) throws ParseException {
    if (l.isEmpty()) {
      throw new ParseException(-1, "Unexpected empty list");
    }
    SExp head = l.get(0);
    if (head.isList()) {
      throw new ParseException(-1, "Expected an operator, but got a list: " + head);
    }
    String cmd = head.asAtom();
    switch (cmd) {
      case "size":
        if (l.size() != 2) {
          throw new ParseException(-1, "Wrong number of arguments for size operator: " + l.size());
        }
        SExp sexp1 = l.get(1);
        if (sexp1.isList()) {
          throw new ParseException(
              -1, "size operator expects a relation symbol, but got a list: " + sexp1);
        }
        String name = sexp1.asAtom();
        SymbolManager sm = prog.getSymbolManager();
        if (!sm.hasName(name)) {
          throw ne
Download .txt
gitextract_eqja_ilo/

├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── maven.yml
│       ├── pages.yml
│       └── submit-deps.yml
├── .gitignore
├── Dockerfile
├── LICENSE.txt
├── README.md
├── changelog.md
├── docs/
│   ├── Gemfile
│   ├── _config.yml
│   ├── eval_modes/
│   │   ├── compile.md
│   │   ├── eager.md
│   │   ├── index.md
│   │   ├── options.md
│   │   └── smt.md
│   ├── index.md
│   ├── lang_ref/
│   │   ├── goal_directed_eval.md
│   │   ├── index.md
│   │   ├── lang_basics.md
│   │   ├── logical_formulas.md
│   │   └── program_safety.md
│   ├── pubs.md
│   ├── starting.md
│   └── tutorial/
│       └── index.md
├── examples/
│   ├── greeting.flg
│   ├── liquid_types.flg
│   ├── symeval.flg
│   └── tutorial.flg
├── license-header
├── misc/
│   └── flg.vim
├── pom.xml
└── src/
    ├── main/
    │   ├── antlr4/
    │   │   └── edu/
    │   │       └── harvard/
    │   │           └── seas/
    │   │               └── pl/
    │   │                   └── formulog/
    │   │                       └── parsing/
    │   │                           └── generated/
    │   │                               └── Formulog.g4
    │   ├── java/
    │   │   └── edu/
    │   │       └── harvard/
    │   │           └── seas/
    │   │               └── pl/
    │   │                   └── formulog/
    │   │                       ├── Configuration.java
    │   │                       ├── FormulogTester.java
    │   │                       ├── Main.java
    │   │                       ├── PrintPreference.java
    │   │                       ├── ast/
    │   │                       │   ├── AbstractRule.java
    │   │                       │   ├── AbstractTerm.java
    │   │                       │   ├── BasicProgram.java
    │   │                       │   ├── BasicRule.java
    │   │                       │   ├── BindingType.java
    │   │                       │   ├── BoolTerm.java
    │   │                       │   ├── ComplexLiteral.java
    │   │                       │   ├── ComplexLiterals.java
    │   │                       │   ├── Constructor.java
    │   │                       │   ├── Constructors.java
    │   │                       │   ├── Expr.java
    │   │                       │   ├── Exprs.java
    │   │                       │   ├── FP32.java
    │   │                       │   ├── FP64.java
    │   │                       │   ├── Fold.java
    │   │                       │   ├── FunctionCallFactory.java
    │   │                       │   ├── Functor.java
    │   │                       │   ├── I32.java
    │   │                       │   ├── I64.java
    │   │                       │   ├── LetFunExpr.java
    │   │                       │   ├── Literal.java
    │   │                       │   ├── MatchClause.java
    │   │                       │   ├── MatchExpr.java
    │   │                       │   ├── Model.java
    │   │                       │   ├── NestedFunctionDef.java
    │   │                       │   ├── OpaqueSet.java
    │   │                       │   ├── Primitive.java
    │   │                       │   ├── Program.java
    │   │                       │   ├── Rule.java
    │   │                       │   ├── SmtLibTerm.java
    │   │                       │   ├── StringTerm.java
    │   │                       │   ├── Term.java
    │   │                       │   ├── Terms.java
    │   │                       │   ├── UnificationPredicate.java
    │   │                       │   ├── UserPredicate.java
    │   │                       │   └── Var.java
    │   │                       ├── codegen/
    │   │                       │   ├── CodeGen.java
    │   │                       │   ├── CodeGenContext.java
    │   │                       │   ├── CodeGenException.java
    │   │                       │   ├── CodeGenUtil.java
    │   │                       │   ├── DeltaFirstQueryPlanner.java
    │   │                       │   ├── FuncsHpp.java
    │   │                       │   ├── FunctorCodeGen.java
    │   │                       │   ├── MainCpp.java
    │   │                       │   ├── MatchCodeGen.java
    │   │                       │   ├── NopQueryPlanner.java
    │   │                       │   ├── PatternMatchTree.java
    │   │                       │   ├── QueryPlanner.java
    │   │                       │   ├── RuleTranslator.java
    │   │                       │   ├── SmtParserCpp.java
    │   │                       │   ├── SmtShimCpp.java
    │   │                       │   ├── SouffleCodeGen.java
    │   │                       │   ├── SymbolCpp.java
    │   │                       │   ├── SymbolHpp.java
    │   │                       │   ├── TemplateSrcFile.java
    │   │                       │   ├── TermCodeGen.java
    │   │                       │   ├── TermCpp.java
    │   │                       │   ├── TypeCodeGen.java
    │   │                       │   ├── TypeCpp.java
    │   │                       │   └── ast/
    │   │                       │       ├── cpp/
    │   │                       │       │   ├── CppAccess.java
    │   │                       │       │   ├── CppBaseTerm.java
    │   │                       │       │   ├── CppBinop.java
    │   │                       │       │   ├── CppBlock.java
    │   │                       │       │   ├── CppCast.java
    │   │                       │       │   ├── CppConst.java
    │   │                       │       │   ├── CppCtor.java
    │   │                       │       │   ├── CppDecl.java
    │   │                       │       │   ├── CppExpr.java
    │   │                       │       │   ├── CppExprFromString.java
    │   │                       │       │   ├── CppFor.java
    │   │                       │       │   ├── CppForEach.java
    │   │                       │       │   ├── CppFuncCall.java
    │   │                       │       │   ├── CppGoto.java
    │   │                       │       │   ├── CppIf.java
    │   │                       │       │   ├── CppLabel.java
    │   │                       │       │   ├── CppMethodCall.java
    │   │                       │       │   ├── CppNewArray.java
    │   │                       │       │   ├── CppNullptr.java
    │   │                       │       │   ├── CppReturn.java
    │   │                       │       │   ├── CppSeq.java
    │   │                       │       │   ├── CppStmt.java
    │   │                       │       │   ├── CppSubscript.java
    │   │                       │       │   ├── CppUnop.java
    │   │                       │       │   ├── CppVar.java
    │   │                       │       │   ├── CppVectorLiteral.java
    │   │                       │       │   └── CppWhile.java
    │   │                       │       └── souffle/
    │   │                       │           ├── SAtom.java
    │   │                       │           ├── SDestructorBody.java
    │   │                       │           ├── SExprBody.java
    │   │                       │           ├── SFunctorBody.java
    │   │                       │           ├── SFunctorCall.java
    │   │                       │           ├── SInfixBinaryOpAtom.java
    │   │                       │           ├── SInt.java
    │   │                       │           ├── SIntList.java
    │   │                       │           ├── SIntListType.java
    │   │                       │           ├── SIntType.java
    │   │                       │           ├── SLit.java
    │   │                       │           ├── SRule.java
    │   │                       │           ├── SRuleMode.java
    │   │                       │           ├── STerm.java
    │   │                       │           ├── SType.java
    │   │                       │           └── SVar.java
    │   │                       ├── db/
    │   │                       │   ├── BindingTypeArrayWrapper.java
    │   │                       │   ├── ExampleComparator.java
    │   │                       │   ├── IndexedFactDb.java
    │   │                       │   ├── IndexedFactDbBuilder.java
    │   │                       │   ├── MinChainCover.java
    │   │                       │   ├── MinIndex.java
    │   │                       │   ├── SortedIndexedFactDb.java
    │   │                       │   └── TupleComparatorGenerator.java
    │   │                       ├── eval/
    │   │                       │   ├── AbstractStratumEvaluator.java
    │   │                       │   ├── EagerStratumEvaluator.java
    │   │                       │   ├── EvalUtil.java
    │   │                       │   ├── Evaluation.java
    │   │                       │   ├── EvaluationException.java
    │   │                       │   ├── EvaluationResult.java
    │   │                       │   ├── IndexedRule.java
    │   │                       │   ├── PredicateFunctionSetter.java
    │   │                       │   ├── RoundBasedStratumEvaluator.java
    │   │                       │   ├── SemiNaiveEvaluation.java
    │   │                       │   ├── SemiNaiveRule.java
    │   │                       │   ├── SmtCallFinder.java
    │   │                       │   ├── StratumEvaluator.java
    │   │                       │   └── UncheckedEvaluationException.java
    │   │                       ├── functions/
    │   │                       │   ├── BuiltInFunctionDefFactory.java
    │   │                       │   ├── DummyFunctionDef.java
    │   │                       │   ├── FunctionDef.java
    │   │                       │   ├── FunctionDefManager.java
    │   │                       │   ├── OpaqueSetOps.java
    │   │                       │   ├── PredicateFunctionDef.java
    │   │                       │   ├── PrimitiveConversions.java
    │   │                       │   ├── RecordAccessor.java
    │   │                       │   └── UserFunctionDef.java
    │   │                       ├── magic/
    │   │                       │   ├── AdornedSymbol.java
    │   │                       │   ├── Adornments.java
    │   │                       │   └── MagicSetTransformer.java
    │   │                       ├── parsing/
    │   │                       │   ├── FactFileParser.java
    │   │                       │   ├── Identifier.java
    │   │                       │   ├── ParseException.java
    │   │                       │   ├── Parser.java
    │   │                       │   ├── ParsingContext.java
    │   │                       │   ├── ParsingUtil.java
    │   │                       │   ├── TermExtractor.java
    │   │                       │   ├── TopLevelParser.java
    │   │                       │   ├── TypeExtractor.java
    │   │                       │   ├── UncheckedParseException.java
    │   │                       │   ├── VariableCheckPass.java
    │   │                       │   └── VariableCheckPassException.java
    │   │                       ├── smt/
    │   │                       │   ├── AbstractSmtLibSolver.java
    │   │                       │   ├── BestMatchSmtManager.java
    │   │                       │   ├── BoolectorProcessFactory.java
    │   │                       │   ├── CallAndResetSolver.java
    │   │                       │   ├── CheckSatAssumingSolver.java
    │   │                       │   ├── Cvc4ProcessFactory.java
    │   │                       │   ├── DoubleCheckingSolver.java
    │   │                       │   ├── ExternalSolverProcessFactory.java
    │   │                       │   ├── NotThreadSafeQueueSmtManager.java
    │   │                       │   ├── PerThreadSmtManager.java
    │   │                       │   ├── PushPopNaiveSolver.java
    │   │                       │   ├── PushPopSolver.java
    │   │                       │   ├── QueueSmtManager.java
    │   │                       │   ├── SingleShotSolver.java
    │   │                       │   ├── SmtLibParser.java
    │   │                       │   ├── SmtLibShim.java
    │   │                       │   ├── SmtLibSolver.java
    │   │                       │   ├── SmtResult.java
    │   │                       │   ├── SmtStatus.java
    │   │                       │   ├── SmtStrategy.java
    │   │                       │   ├── YicesProcessFactory.java
    │   │                       │   └── Z3ProcessFactory.java
    │   │                       ├── symbols/
    │   │                       │   ├── AbstractSymbol.java
    │   │                       │   ├── AbstractTypedSymbol.java
    │   │                       │   ├── AbstractWrappedRelationSymbol.java
    │   │                       │   ├── BuiltInConstructorGetterSymbol.java
    │   │                       │   ├── BuiltInConstructorSymbol.java
    │   │                       │   ├── BuiltInConstructorTesterSymbol.java
    │   │                       │   ├── BuiltInFunctionSymbol.java
    │   │                       │   ├── BuiltInTypeSymbol.java
    │   │                       │   ├── ConstructorSymbol.java
    │   │                       │   ├── ConstructorSymbolImpl.java
    │   │                       │   ├── ConstructorSymbolType.java
    │   │                       │   ├── FunctionSymbol.java
    │   │                       │   ├── GlobalSymbolManager.java
    │   │                       │   ├── MutableRelationSymbol.java
    │   │                       │   ├── PredicateFunctionSymbol.java
    │   │                       │   ├── RecordSymbol.java
    │   │                       │   ├── RelationSymbol.java
    │   │                       │   ├── Symbol.java
    │   │                       │   ├── SymbolComparator.java
    │   │                       │   ├── SymbolManager.java
    │   │                       │   ├── TypeSymbol.java
    │   │                       │   ├── TypeSymbolImpl.java
    │   │                       │   ├── TypeSymbolType.java
    │   │                       │   ├── TypedSymbol.java
    │   │                       │   ├── WrappedRelationSymbol.java
    │   │                       │   └── parameterized/
    │   │                       │       ├── AbstractParameterizedSymbol.java
    │   │                       │       ├── BuiltInConstructorSymbolBase.java
    │   │                       │       ├── FunctorBase.java
    │   │                       │       ├── Param.java
    │   │                       │       ├── ParamKind.java
    │   │                       │       ├── ParameterizedConstructorSymbol.java
    │   │                       │       ├── ParameterizedSymbol.java
    │   │                       │       └── SymbolBase.java
    │   │                       ├── types/
    │   │                       │   ├── BuiltInTypes.java
    │   │                       │   ├── FunctorType.java
    │   │                       │   ├── IndexedType.java
    │   │                       │   ├── TypeAlias.java
    │   │                       │   ├── TypeChecker.java
    │   │                       │   ├── TypeException.java
    │   │                       │   ├── TypeManager.java
    │   │                       │   ├── Types.java
    │   │                       │   └── WellTypedProgram.java
    │   │                       ├── unification/
    │   │                       │   ├── EmptySubstitution.java
    │   │                       │   ├── OverwriteSubstitution.java
    │   │                       │   ├── SimpleSubstitution.java
    │   │                       │   ├── Substitution.java
    │   │                       │   └── Unification.java
    │   │                       ├── util/
    │   │                       │   ├── AbstractFJPTask.java
    │   │                       │   ├── CompositeIterable.java
    │   │                       │   ├── CountingFJP.java
    │   │                       │   ├── CountingFJPImpl.java
    │   │                       │   ├── Dataset.java
    │   │                       │   ├── DedupWorkList.java
    │   │                       │   ├── EnumerableThreadLocal.java
    │   │                       │   ├── ExceptionalFunction.java
    │   │                       │   ├── FunctorUtil.java
    │   │                       │   ├── IntArrayWrapper.java
    │   │                       │   ├── MockCountingFJP.java
    │   │                       │   ├── Pair.java
    │   │                       │   ├── SharedLong.java
    │   │                       │   ├── StackMap.java
    │   │                       │   ├── TodoException.java
    │   │                       │   ├── Triple.java
    │   │                       │   ├── UnionFind.java
    │   │                       │   ├── Util.java
    │   │                       │   └── sexp/
    │   │                       │       ├── SExp.java
    │   │                       │       ├── SExpAtom.java
    │   │                       │       ├── SExpException.java
    │   │                       │       ├── SExpLexer.java
    │   │                       │       ├── SExpList.java
    │   │                       │       ├── SExpParser.java
    │   │                       │       └── SExpToken.java
    │   │                       └── validating/
    │   │                           ├── FunctionDefValidation.java
    │   │                           ├── InvalidProgramException.java
    │   │                           ├── Stratifier.java
    │   │                           ├── Stratum.java
    │   │                           ├── ValidRule.java
    │   │                           └── ast/
    │   │                               ├── Assignment.java
    │   │                               ├── Check.java
    │   │                               ├── Destructor.java
    │   │                               ├── SimpleLiteral.java
    │   │                               ├── SimpleLiteralExnVisitor.java
    │   │                               ├── SimpleLiteralTag.java
    │   │                               ├── SimpleLiteralVisitor.java
    │   │                               ├── SimplePredicate.java
    │   │                               └── SimpleRule.java
    │   └── resources/
    │       └── codegen/
    │           ├── .gitignore
    │           ├── CMakeLists.txt
    │           └── src/
    │               ├── ConcurrentHashMap.hpp
    │               ├── Symbol.cpp
    │               ├── Symbol.hpp
    │               ├── Term.cpp
    │               ├── Term.hpp
    │               ├── Tuple.hpp
    │               ├── Type.cpp
    │               ├── Type.hpp
    │               ├── formulog.dl
    │               ├── funcs.hpp
    │               ├── functors.cpp
    │               ├── functors.h
    │               ├── globals.h
    │               ├── main.cpp
    │               ├── parser.cpp
    │               ├── parser.hpp
    │               ├── set.cpp
    │               ├── set.hpp
    │               ├── smt_parser.cpp
    │               ├── smt_parser.hpp
    │               ├── smt_shim.cpp
    │               ├── smt_shim.h
    │               ├── smt_solver.cpp
    │               ├── smt_solver.h
    │               └── time.hpp
    └── test/
        ├── java/
        │   └── edu/
        │       └── harvard/
        │           └── seas/
        │               └── pl/
        │                   └── formulog/
        │                       ├── codegen/
        │                       │   ├── CodeGenTester.java
        │                       │   ├── CompiledEagerEvaluationTest.java
        │                       │   ├── CompiledEagerMagicSetTest.java
        │                       │   ├── CompiledSemiNaiveEvaluationTest.java
        │                       │   ├── CompiledSemiNaiveMagicSetTest.java
        │                       │   └── NopTester.java
        │                       ├── eval/
        │                       │   ├── AbstractEvaluationTest.java
        │                       │   ├── AbstractTester.java
        │                       │   ├── CommonEvaluationTest.java
        │                       │   ├── EagerSemiNaiveEvaluationTest.java
        │                       │   ├── InterpretedSemiNaiveTester.java
        │                       │   ├── SemiNaiveEvaluationTest.java
        │                       │   └── Tester.java
        │                       ├── magic/
        │                       │   ├── CommonMagicSetTest.java
        │                       │   ├── EagerSemiNaiveMagicSetTest.java
        │                       │   └── SemiNaiveMagicSetTest.java
        │                       ├── parsing/
        │                       │   └── ParsingTest.java
        │                       ├── types/
        │                       │   └── TypeCheckingTest.java
        │                       └── validating/
        │                           ├── SemiNaiveValidatingTest.java
        │                           └── ValidatingTest.java
        └── resources/
            ├── test001_ok.flg
            ├── test002_ok.flg
            ├── test003_ok.flg
            ├── test004_ok.flg
            ├── test005_ok.flg
            ├── test006_ok.flg
            ├── test007_ok.flg
            ├── test008_ok.flg
            ├── test009_ok.flg
            ├── test010_ok.flg
            ├── test011_ok.flg
            ├── test012_bd.flg
            ├── test013_ok.flg
            ├── test014_ok.flg
            ├── test015_ok.flg
            ├── test016_ok.flg
            ├── test017_ok.flg
            ├── test018_ok.flg
            ├── test019_ok.flg
            ├── test020_ok.flg
            ├── test021_ok.flg
            ├── test022_ok.flg
            ├── test023_ok.flg
            ├── test024_ok.flg
            ├── test025_bd.flg
            ├── test026_bd.flg
            ├── test027_ok.flg
            ├── test028_ok.flg
            ├── test029_ok.flg
            ├── test030_ok.flg
            ├── test031_ok.flg
            ├── test032_ok.flg
            ├── test033_ok.flg
            ├── test034_ok.flg
            ├── test035_ok.flg
            ├── test036_ok.flg
            ├── test037_ok.flg
            ├── test038_ok.flg
            ├── test039_ok.flg
            ├── test040_ok.flg
            ├── test041_ok.flg
            ├── test042_ok.flg
            ├── test043_ok.flg
            ├── test044_ok.flg
            ├── test045_ok.flg
            ├── test046_ok.flg
            ├── test047_ok.flg
            ├── test048_ok.flg
            ├── test049_ok.flg
            ├── test050_bd.flg
            ├── test051_bd.flg
            ├── test052_bd.flg
            ├── test053_ok.flg
            ├── test054_ok.flg
            ├── test055_bd.flg
            ├── test056_ok.flg
            ├── test057_ok.flg
            ├── test058_ok.flg
            ├── test059_ok.flg
            ├── test060_ok.flg
            ├── test061_ok.flg
            ├── test062_ok.flg
            ├── test063_ok.flg
            ├── test064_ok.flg
            ├── test065_ok.flg
            ├── test066_ok.flg
            ├── test067_ok.flg
            ├── test068_ok.flg
            ├── test069_ok.flg
            ├── test070_ok.flg
            ├── test071_ok.flg
            ├── test072_ok.flg
            ├── test073_ok.flg
            ├── test074_ok.flg
            ├── test075_ok.flg
            ├── test076_ok.flg
            ├── test077_ok.flg
            ├── test078_ok.flg
            ├── test079_ok.flg
            ├── test080_bd.flg
            ├── test081_ok.flg
            ├── test082_ok.flg
            ├── test083_ok.flg
            ├── test084_ok.flg
            ├── test085_ok.flg
            ├── test086_ok.flg
            ├── test087_ok.flg
            ├── test088_ok.flg
            ├── test089_ok.flg
            ├── test090_ok.flg
            ├── test091_bd.flg
            ├── test092_ok.flg
            ├── test093_ok.flg
            ├── test094_ok.flg
            ├── test095_ok.flg
            ├── test096_ok.flg
            ├── test097_ok.flg
            ├── test098_bd.flg
            ├── test099_ok.flg
            ├── test100_ok.flg
            ├── test101_ok.flg
            ├── test102_ok.flg
            ├── test103_ok.flg
            ├── test104_ok.flg
            ├── test105_ok.flg
            ├── test106_ok.flg
            ├── test107_ok.flg
            ├── test108_ok.flg
            ├── test109_ok.flg
            ├── test110_ok.flg
            ├── test111_ok.flg
            ├── test112_ok.flg
            ├── test113_ok.flg
            ├── test114_ok.flg
            ├── test115_ok.flg
            ├── test116_ok.flg
            ├── test117_ok.flg
            ├── test118_bd.flg
            ├── test119_ok.flg
            ├── test120_ok.flg
            ├── test121_ok.flg
            ├── test122_ok.flg
            ├── test123_ok.flg
            ├── test124_ok.flg
            ├── test125_ok.flg
            ├── test126_ok.flg
            ├── test127_ok.flg
            ├── test128_ok.flg
            ├── test129_ok.flg
            ├── test130_bd.flg
            ├── test131_bd.flg
            ├── test132_bd.flg
            ├── test133_ok.flg
            ├── test134_ok.flg
            ├── test135_ok.flg
            ├── test136_ok.flg
            ├── test137_ok.flg
            ├── test138_ok.flg
            ├── test139_ok.flg
            ├── test140_ok.flg
            ├── test141_ok.flg
            ├── test142_ok.flg
            ├── test143_ok.flg
            ├── test144_ok.flg
            ├── test145_ok.flg
            ├── test146_ok.flg
            ├── test147_ok.flg
            ├── test148_ok.flg
            ├── test149_ok.flg
            ├── test150_ok.flg
            ├── test151_ok.flg
            ├── test152_ok.flg
            ├── test153_ok.flg
            ├── test154_ok.flg
            ├── test155_ok.flg
            ├── test156_ok.flg
            ├── test157_ok.flg
            ├── test158_ok.flg
            ├── test159_ok.flg
            ├── test160_ok.flg
            ├── test161_ok.flg
            ├── test162_ok.flg
            ├── test163_ok.flg
            ├── test164_ok.flg
            ├── test165_ok.flg
            ├── test166_ok.flg
            ├── test167_ok.flg
            ├── test168_ok.flg
            ├── test169_ok.flg
            ├── test170_ok.flg
            ├── test171_ok.flg
            ├── test172_ok.flg
            ├── test173_ok.flg
            ├── test174_ok.flg
            ├── test175_ok.flg
            ├── test176_ok.flg
            ├── test177_ok.flg
            ├── test178_ok.flg
            ├── test179_ok.flg
            ├── test180_ok.flg
            ├── test181_ok.flg
            ├── test182_ok.flg
            ├── test183_ok.flg
            ├── test184_ok.flg
            ├── test185_bd.flg
            ├── test186_ok.flg
            ├── test187_ok.flg
            ├── test188_bd.flg
            ├── test189_ok.flg
            ├── test190_ok.flg
            ├── test191_input/
            │   ├── complex_terms.tsv
            │   ├── names.tsv
            │   └── numbers.tsv
            ├── test191_ok.flg
            ├── test192_ok.flg
            ├── test193_ok.flg
            ├── test217_bd.flg
            ├── test218_bd.flg
            ├── test219_ok.flg
            ├── test220_ok.flg
            ├── test221_ok.flg
            ├── test222_ok.flg
            ├── test223_ok.flg
            ├── test224_ok.flg
            ├── test225_ok.flg
            ├── test226_ok.flg
            ├── test227_ok.flg
            ├── test228_ok.flg
            ├── test229_ok.flg
            ├── test230_ok.flg
            ├── test231_ok.flg
            ├── test232_ok.flg
            ├── test233_ok.flg
            ├── test234_ok.flg
            ├── test235_ok.flg
            ├── test236_ok.flg
            ├── test237_ok.flg
            ├── test238_ok.flg
            ├── test240_ok.flg
            ├── test241_ok.flg
            ├── test242_ok.flg
            ├── test243_ok.flg
            ├── test244_ok.flg
            ├── test245_ok.flg
            ├── test248_bd.flg
            ├── test249_ok.flg
            ├── test250_ok.flg
            ├── test251_bd.flg
            ├── test252_ok.flg
            ├── test253_ok.flg
            ├── test254_ok.flg
            ├── test255_bd.flg
            ├── test256_ok.flg
            ├── test257_ok.flg
            ├── test258_ok.flg
            ├── test259_ok.flg
            ├── test260_ok.flg
            ├── test261_ok.flg
            ├── test262_ok.flg
            ├── test263_ok.flg
            ├── test264_ok.flg
            ├── test265_ok.flg
            ├── test266_bd.flg
            ├── test267_ok.flg
            ├── test268_bd.flg
            ├── test269_bd.flg
            ├── test270_bd.flg
            ├── test271_bd.flg
            ├── test272_bd.flg
            ├── test273_ok.flg
            ├── test274_ok.flg
            ├── test275_ok.flg
            ├── test276_inputA/
            │   └── foo.tsv
            ├── test276_inputB/
            │   └── foo.tsv
            ├── test276_ok.flg
            ├── test277_ok.flg
            ├── test278_ok.flg
            ├── test279_ok.flg
            ├── test280_ok.flg
            ├── test281_ok.flg
            ├── test282_ok.flg
            ├── test283_ok.flg
            ├── test284_ok.flg
            ├── test285_ok.flg
            ├── test286_ok.flg
            ├── test287_ok.flg
            ├── test288_ok.flg
            ├── test289_ok.flg
            ├── test290_ok.flg
            ├── test291_ok.flg
            ├── test292_ok.flg
            ├── test293_ok.flg
            ├── test294_ok.flg
            ├── test295_bd.flg
            ├── test296_bd.flg
            ├── test297_ok.flg
            ├── test298_ok.flg
            ├── test299_ok.flg
            ├── test300_ok.flg
            ├── test301_ok.flg
            ├── test302_bd.flg
            ├── test303_ok.flg
            ├── test304_ok.flg
            ├── test305_ok.flg
            ├── test306_ok.flg
            ├── test307_ok.flg
            ├── test308_ok.flg
            ├── test309_ok.flg
            ├── test310_ok.flg
            ├── test311_ok.flg
            ├── test312_bd.flg
            ├── test313_bd.flg
            ├── test314_bd.flg
            ├── test315_bd.flg
            ├── test316_ok.flg
            ├── test317_ok.flg
            ├── test318_ok.flg
            ├── test319_ok.flg
            ├── test320_ok.flg
            ├── test321_ok.flg
            ├── test322_bd.flg
            ├── test323_ok.flg
            ├── test324_ok.flg
            ├── test325_ok.flg
            ├── test326_ok.flg
            ├── test327_bd.flg
            ├── test328_ok.flg
            ├── test329_ok.flg
            ├── test330_ok.flg
            ├── test331_ok.flg
            ├── test332_ok.flg
            ├── test333_bd.flg
            ├── test334_ok.flg
            ├── test335_bd.flg
            ├── test336_ok.flg
            ├── test337_ok.flg
            ├── test338_ok.flg
            ├── test339_ok.flg
            ├── test340_ok.flg
            ├── test341_bd.flg
            ├── test342_bd.flg
            ├── test343_bd.flg
            ├── test344_bd.flg
            └── test345_ok.flg
Download .txt
Showing preview only (257K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3392 symbols across 304 files)

FILE: src/main/java/edu/harvard/seas/pl/formulog/Configuration.java
  class Configuration (line 53) | public final class Configuration {
    method Configuration (line 55) | private Configuration() {
    method recordSmtTime (line 92) | public static void recordSmtTime(long delta) {
    method getSmtTotalTime (line 96) | public static long getSmtTotalTime() {
    method memoizeThreshold (line 176) | public static final int memoizeThreshold() {
    class SmtStats (line 198) | public static class SmtStats {
      method add (line 202) | public void add(long time) {
    method run (line 220) | @Override
    method run (line 231) | @Override
    method run (line 242) | @Override
    method run (line 252) | @Override
    method printConfiguration (line 259) | public static synchronized void printConfiguration(PrintStream out) {
    method recordSmtDeclTime (line 271) | public static void recordSmtDeclTime(long time) {
    method recordSmtInferTime (line 275) | public static void recordSmtInferTime(long time) {
    method recordSmtSerialTime (line 279) | public static void recordSmtSerialTime(long time) {
    method recordSmtEvalTime (line 283) | public static void recordSmtEvalTime(
    method recordSmtWaitTime (line 308) | public static void recordSmtWaitTime(long time) {
    method recordSmtDeclGlobalsTime (line 312) | public static void recordSmtDeclGlobalsTime(long time) {
    method printSmtDiagnostics (line 316) | public static synchronized void printSmtDiagnostics(PrintStream out) {
    method recordPushPopSolverStats (line 367) | public static void recordPushPopSolverStats(
    method recordCsaCacheStats (line 376) | public static void recordCsaCacheStats(int solverId, int hits, int mis...
    method recordSmtDoubleCheck (line 385) | public static void recordSmtDoubleCheck(boolean falseUnknown) {
    method recordCsaCacheClear (line 392) | public static void recordCsaCacheClear(int solverId) {
    method recordFuncTime (line 396) | public static void recordFuncTime(FunctionSymbol func, long time) {
    method getFuncDiagnostics (line 401) | public static Map<FunctionSymbol, AtomicLong> getFuncDiagnostics() {
    method printFuncDiagnostics (line 405) | public static synchronized void printFuncDiagnostics(PrintStream out) {
    method compare (line 420) | @Override
    method compare (line 429) | @Override
    method getTotal (line 435) | private long getTotal(Entry<?, Pair<AtomicLong, AtomicLong>> e) {
    method recordRulePrefixTime (line 441) | public static void recordRulePrefixTime(Rule<?, ?> rule, long time) {
    method recordRuleSuffixTime (line 447) | public static void recordRuleSuffixTime(Rule<?, ?> rule, long time) {
    method printRuleDiagnostics (line 453) | public static synchronized void printRuleDiagnostics(PrintStream out) {
    method printRelSizes (line 470) | public static synchronized void printRelSizes(
    method propIsSet (line 489) | private static boolean propIsSet(String prop, boolean defaultValue) {
    method propIsSet (line 503) | private static boolean propIsSet(String prop) {
    method getIntProp (line 507) | static int getIntProp(String prop, int def) {
    method getStringProp (line 519) | private static String getStringProp(String prop, String def) {
    method getListProp (line 527) | static List<String> getListProp(String prop) {
    method breakIntoCollection (line 537) | private static void breakIntoCollection(String s, Collection<String> a...
    method getSmtStrategy (line 550) | static SmtStrategy getSmtStrategy() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/FormulogTester.java
  class FormulogTester (line 61) | public class FormulogTester {
    method setup (line 67) | public synchronized void setup(Reader program, File testFile)
    method loadTests (line 75) | private void loadTests(File testFile, Parser parser) throws IOExceptio...
    method loadTest (line 85) | private FormulogTest loadTest(JsonNode test, Path rootTestDir, Parser ...
    method parseBoolLogic (line 105) | private Function<EvaluationResult, List<String>> parseBoolLogic(String...
    method parseBoolLogic (line 117) | private Function<EvaluationResult, List<String>> parseBoolLogic(SExp s...
    method parseBoolAtom (line 125) | private Function<EvaluationResult, List<String>> parseBoolAtom(String ...
    method parseBoolList (line 135) | private Function<EvaluationResult, List<String>> parseBoolList(List<SE...
    method parseIntLogic (line 193) | private Function<EvaluationResult, Integer> parseIntLogic(SExp sexp) t...
    method parseIntAtom (line 201) | private Function<EvaluationResult, Integer> parseIntAtom(String s) thr...
    method parseIntList (line 210) | private Function<EvaluationResult, Integer> parseIntList(List<SExp> l)...
    method runTests (line 245) | synchronized boolean runTests() throws InvalidProgramException, Evalua...
    method clearCachedState (line 261) | private void clearCachedState() {
    method runTest (line 273) | private boolean runTest(FormulogTest test, Map<RelationSymbol, Set<Ter...
    class FormulogTest (line 302) | private static class FormulogTest {
      method FormulogTest (line 307) | public FormulogTest(
    method main (line 317) | public static void main(String[] args) throws Exception {
    method main (line 329) | public static void main(File file, File json) throws Exception {

FILE: src/main/java/edu/harvard/seas/pl/formulog/Main.java
  class Main (line 69) | @Command(
    method go (line 144) | private void go() {
    method parse (line 168) | private BasicProgram parse() {
    method typeCheck (line 194) | private WellTypedProgram typeCheck(Program<UserPredicate, BasicRule> p...
    method setup (line 209) | private Evaluation setup(WellTypedProgram prog) {
    method evaluate (line 224) | private void evaluate(Evaluation eval) {
    method getBanner (line 237) | private String getBanner(String heading) {
    method getSmallBanner (line 241) | private String getSmallBanner(String heading) {
    class FactFileDumper (line 245) | private static class FactFileDumper implements Runnable {
      method FactFileDumper (line 250) | public FactFileDumper(Iterable<UserPredicate> facts, PrintStream out) {
      method run (line 255) | @Override
    method dumpResultsToDisk (line 271) | private void dumpResultsToDisk(EvaluationResult res) {
    method printSmtStats (line 293) | private void printSmtStats(PrintStream out) {
    method dumpResults (line 318) | private void dumpResults(EvaluationResult res) {
    method dumpRelations (line 367) | private void dumpRelations(
    class SmtModeConverter (line 387) | public static class SmtModeConverter implements ITypeConverter<SmtStra...
      method convert (line 389) | @Override
    method main (line 407) | public static void main(String[] args) throws Exception {
    method handleException (line 412) | private static void handleException(String msg, Exception e) {
    method call (line 421) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/PrintPreference.java
  type PrintPreference (line 22) | public enum PrintPreference {

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/AbstractRule.java
  class AbstractRule (line 25) | public abstract class AbstractRule<H extends Literal, B extends Literal>...
    method AbstractRule (line 30) | protected AbstractRule(H head, List<B> body) {
    method iterator (line 35) | @Override
    method getHead (line 40) | @Override
    method getBodySize (line 45) | @Override
    method getBody (line 50) | @Override
    method toString (line 55) | @Override
    method hashCode (line 75) | @Override
    method equals (line 84) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/AbstractTerm.java
  class AbstractTerm (line 22) | public abstract class AbstractTerm implements Term {
    method AbstractTerm (line 26) | public AbstractTerm() {
    method getId (line 30) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/BasicProgram.java
  type BasicProgram (line 22) | public interface BasicProgram extends Program<UserPredicate, BasicRule> {}

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/BasicRule.java
  class BasicRule (line 25) | public class BasicRule extends AbstractRule<UserPredicate, ComplexLitera...
    method BasicRule (line 27) | private BasicRule(UserPredicate head, List<ComplexLiteral> body) {
    method make (line 35) | public static BasicRule make(UserPredicate head, List<ComplexLiteral> ...
    method make (line 42) | public static BasicRule make(UserPredicate head) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/BindingType.java
  type BindingType (line 22) | public enum BindingType {
    method isBound (line 27) | public boolean isBound() {
    method isFree (line 31) | public boolean isFree() {
    method isIgnored (line 35) | public boolean isIgnored() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/BoolTerm.java
  class BoolTerm (line 30) | public class BoolTerm extends AbstractTerm implements Primitive<Boolean>...
    method BoolTerm (line 36) | private BoolTerm(boolean val) {
    method mk (line 40) | public static BoolTerm mk(boolean val) {
    method mkTrue (line 44) | public static BoolTerm mkTrue() {
    method mkFalse (line 48) | public static BoolTerm mkFalse() {
    method getVal (line 52) | @Override
    method getType (line 57) | @Override
    method toSmtLib (line 62) | @Override
    method substSolverTerms (line 67) | @Override
    method freeVars (line 72) | @Override
    method toString (line 77) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/ComplexLiteral.java
  type ComplexLiteral (line 28) | public interface ComplexLiteral extends Literal {
    method getArgs (line 30) | Term[] getArgs();
    method applySubstitution (line 32) | ComplexLiteral applySubstitution(Substitution subst);
    method isNegated (line 34) | boolean isNegated();
    method varSet (line 36) | default Set<Var> varSet() {
    method accept (line 44) | <I, O> O accept(ComplexLiteralVisitor<I, O> visitor, I input);
    method accept (line 46) | <I, O, E extends Throwable> O accept(ComplexLiteralExnVisitor<I, O, E>...

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/ComplexLiterals.java
  class ComplexLiterals (line 22) | public final class ComplexLiterals {
    method ComplexLiterals (line 24) | private ComplexLiterals() {
    method unifyWithBool (line 28) | public static UnificationPredicate unifyWithBool(Term t, boolean bool) {
    method trueAtom (line 32) | public static UnificationPredicate trueAtom() {
    type ComplexLiteralVisitor (line 36) | public static interface ComplexLiteralVisitor<I, O> {
      method visit (line 38) | O visit(UnificationPredicate unificationPredicate, I input);
      method visit (line 40) | O visit(UserPredicate userPredicate, I input);
    type ComplexLiteralExnVisitor (line 43) | public static interface ComplexLiteralExnVisitor<I, O, E extends Throw...
      method visit (line 45) | O visit(UnificationPredicate unificationPredicate, I input) throws E;
      method visit (line 47) | O visit(UserPredicate userPredicate, I input) throws E;

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Constructor.java
  type Constructor (line 28) | public interface Constructor extends Functor<ConstructorSymbol>, SmtLibT...
    method accept (line 30) | @Override
    method accept (line 35) | @Override
    method applySubstitution (line 40) | @Override
    method copyWithNewArgs (line 53) | @Override
    method normalize (line 56) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Constructors.java
  class Constructors (line 53) | public final class Constructors {
    method Constructors (line 55) | private Constructors() {
    method make (line 61) | public static Constructor make(ConstructorSymbol sym, Term[] args) {
    method makeZeroAry (line 91) | public static Constructor makeZeroAry(ConstructorSymbol sym) {
    method nil (line 97) | public static Constructor nil() {
    method cons (line 101) | public static Constructor cons(Term hd, Term tl) {
    method none (line 107) | public static final Term none() {
    method some (line 111) | public static Term some(Term arg) {
    method tuple (line 115) | public static Term tuple(Term... args) {
    method lookupOrCreateBuiltInConstructor (line 119) | private static Constructor lookupOrCreateBuiltInConstructor(
    method makeAnd (line 242) | private static Constructor makeAnd(Term[] args) {
    method makeOr (line 252) | private static Constructor makeOr(Term[] args) {
    method renameBinder (line 268) | private static SolverVariable renameBinder(SolverVariable x) {
    class SolverLet (line 275) | private static class SolverLet extends AbstractConstructor<Constructor...
      method make (line 277) | public static Constructor make(ConstructorSymbol sym, Term[] args) {
      method SolverLet (line 286) | private SolverLet(ConstructorSymbol sym, Term[] args) {
      method toSmtLib (line 290) | @Override
      method substSolverTerms (line 301) | @Override
      method toString (line 313) | @Override
      method freeVars (line 318) | @Override
    class Quantifier (line 327) | private static class Quantifier extends AbstractConstructor<BuiltInCon...
      method Quantifier (line 329) | protected Quantifier(BuiltInConstructorSymbol sym, Term[] args) {
      method isExists (line 333) | private boolean isExists() {
      method toSmtLib (line 337) | @Override
      method substSolverTerms (line 388) | @Override
      method getPatterns (line 406) | protected List<List<Term>> getPatterns() {
      method getBoundVars (line 414) | private List<SolverVariable> getBoundVars() {
      method freeVars (line 424) | @Override
    class Nil (line 432) | private static class Nil extends AbstractConstructor<ConstructorSymbol> {
      method Nil (line 434) | protected Nil(ConstructorSymbol sym, Term[] args) {
      method toSmtLib (line 438) | @Override
      method toString (line 443) | @Override
    class Cons (line 449) | private static class Cons extends AbstractConstructor<ConstructorSymbo...
      method Cons (line 451) | protected Cons(ConstructorSymbol sym, Term[] args) {
      method toSmtLib (line 455) | @Override
      method toString (line 460) | @Override
    method makeNil (line 489) | private static Constructor makeNil(ConstructorSymbol sym, Term[] args) {
    method makeCons (line 493) | private static Constructor makeCons(ConstructorSymbol sym, Term[] args) {
    method makeIntConst (line 497) | private static Constructor makeIntConst(ConstructorSymbol sym, Term[] ...
    method lookupOrCreateParameterizedConstructor (line 516) | private static Constructor lookupOrCreateParameterizedConstructor(
    method nat (line 594) | private static int nat(Param param) {
    method nat (line 598) | private static int nat(ParameterizedConstructorSymbol sym, int idx) {
    method makeBvConst (line 602) | private static Constructor makeBvConst(ParameterizedConstructorSymbol ...
    method makeBvBigConst (line 619) | private static Constructor makeBvBigConst(ParameterizedConstructorSymb...
    method formatBitString (line 636) | private static String formatBitString(String bitString, int width) {
    method makeIntToBv (line 650) | private static Constructor makeIntToBv(ParameterizedConstructorSymbol ...
    method makeBvExtract (line 667) | private static Constructor makeBvExtract(ParameterizedConstructorSymbo...
    method makeConstant (line 683) | private static Constructor makeConstant(ConstructorSymbol sym, Term[] ...
    method makeBvToBvSigned (line 697) | private static Constructor makeBvToBvSigned(ParameterizedConstructorSy...
    method makeBvToBvUnsigned (line 726) | private static Constructor makeBvToBvUnsigned(ParameterizedConstructor...
    method makeBvToFp (line 755) | private static Constructor makeBvToFp(ParameterizedConstructorSymbol s...
    method makeFpToFp (line 773) | private static Constructor makeFpToFp(ParameterizedConstructorSymbol s...
    method makeFpToBv (line 791) | private static Constructor makeFpToBv(
    class AbstractConstructor (line 810) | private abstract static class AbstractConstructor<S extends Constructo...
      method AbstractConstructor (line 818) | protected AbstractConstructor(S sym, Term[] args) {
      method noneNull (line 832) | private boolean noneNull(Term[] ts) {
      method isGround (line 841) | @Override
      method containsUnevaluatedTerm (line 846) | @Override
      method getSymbol (line 851) | @Override
      method getArgs (line 856) | @Override
      method toString (line 861) | @Override
      method copyWithNewArgs (line 866) | @Override
      method substSolverTerms (line 871) | @Override
      method freeVars (line 883) | @Override
    class VanillaConstructor (line 893) | public static class VanillaConstructor extends AbstractConstructor<Con...
      method VanillaConstructor (line 895) | private VanillaConstructor(ConstructorSymbol sym, Term[] args) {
      method toSmtLib (line 899) | @Override
    class Tuple (line 905) | public static class Tuple extends AbstractConstructor<TupleSymbol> {
      method Tuple (line 907) | private Tuple(TupleSymbol sym, Term[] args) {
      method toSmtLib (line 911) | @Override
      method toString (line 916) | @Override
    class Record (line 930) | public static class Record extends AbstractConstructor<ConstructorSymb...
      method Record (line 932) | private Record(RecordSymbol sym, Term[] args) {
      method toSmtLib (line 936) | @Override
      method toString (line 941) | @Override
    class SolverVariable (line 957) | public static class SolverVariable extends AbstractConstructor<Paramet...
      method SolverVariable (line 963) | public SolverVariable(ParameterizedConstructorSymbol sym, Term[] arg...
      method toSmtLib (line 967) | @Override
      method getSolverVarId (line 972) | public int getSolverVarId() {
      method toString (line 976) | @Override
      method freeVars (line 986) | @Override
    method makeConstructorTester (line 992) | private static Constructor makeConstructorTester(ConstructorSymbol sym...
    method makeConstructorGetter (line 1008) | private static Constructor makeConstructorGetter(ConstructorSymbol sym...
    class SolverUninterpretedFunction (line 1023) | public static class SolverUninterpretedFunction extends AbstractConstr...
      method SolverUninterpretedFunction (line 1025) | protected SolverUninterpretedFunction(ConstructorSymbol sym, Term[] ...
      method toSmtLib (line 1029) | @Override
    class SolverOperation (line 1035) | public static class SolverOperation extends AbstractConstructor<Constr...
      method SolverOperation (line 1039) | protected SolverOperation(ConstructorSymbol sym, Term[] args, String...
      method toSmtLib (line 1044) | @Override
      method getSyntax (line 1049) | private String getSyntax() {
      method toString (line 1074) | @Override
    class SolverIte (line 1090) | private static class SolverIte extends SolverOperation {
      method SolverIte (line 1092) | protected SolverIte(ConstructorSymbol sym, Term[] args) {
      method toString (line 1096) | @Override
    method toSmtLib (line 1102) | private static void toSmtLib(Constructor c, String repr, SmtLibShim sh...
    method toSmtLib (line 1127) | private static void toSmtLib(Constructor c, SmtLibShim shim) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Expr.java
  type Expr (line 27) | public interface Expr extends Term {
    method accept (line 29) | <I, O> O accept(ExprVisitor<I, O> visitor, I in);
    method accept (line 31) | <I, O, E extends Throwable> O accept(ExprVisitorExn<I, O, E> visitor, ...
    method accept (line 33) | @Override
    method accept (line 38) | @Override
    method containsUnevaluatedTerm (line 43) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Exprs.java
  class Exprs (line 24) | public final class Exprs {
    method Exprs (line 26) | private Exprs() {
    type ExprVisitor (line 30) | public static interface ExprVisitor<I, O> {
      method visit (line 32) | O visit(MatchExpr matchExpr, I in);
      method visit (line 34) | O visit(FunctionCall funcCall, I in);
      method visit (line 36) | O visit(LetFunExpr funcDefs, I in);
      method visit (line 38) | O visit(Fold fold, I in);
    type ExprVisitorExn (line 41) | public static interface ExprVisitorExn<I, O, E extends Throwable> {
      method visit (line 43) | O visit(MatchExpr matchExpr, I in) throws E;
      method visit (line 45) | O visit(FunctionCall funcCall, I in) throws E;
      method visit (line 47) | O visit(LetFunExpr funcDefs, I in) throws E;
      method visit (line 49) | O visit(Fold fold, I in) throws E;

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/FP32.java
  class FP32 (line 33) | public class FP32 extends AbstractTerm implements Primitive<Float>, SmtL...
    method FP32 (line 38) | private FP32(float val) {
    method make (line 42) | public static FP32 make(float val) {
    method getVal (line 46) | @Override
    method toString (line 51) | @Override
    method substSolverTerms (line 65) | @Override
    method toSmtLib (line 70) | @Override
    method getType (line 83) | @Override
    method freeVars (line 88) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/FP64.java
  class FP64 (line 33) | public class FP64 extends AbstractTerm implements Primitive<Double>, Smt...
    method FP64 (line 38) | private FP64(double val) {
    method make (line 42) | public static FP64 make(double val) {
    method getVal (line 46) | @Override
    method toString (line 51) | @Override
    method substSolverTerms (line 65) | @Override
    method toSmtLib (line 70) | @Override
    method getType (line 83) | @Override
    method freeVars (line 88) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Fold.java
  class Fold (line 34) | public class Fold implements Expr {
    method Fold (line 41) | private Fold(FunctionSymbol f, Term[] args, FunctionCallFactory funCal...
    method mk (line 57) | public static Fold mk(FunctionSymbol f, Term[] args, FunctionCallFacto...
    method getArgs (line 61) | public Term[] getArgs() {
    method getFunction (line 65) | public FunctionSymbol getFunction() {
    method getShamCall (line 69) | public FunctionCall getShamCall() {
    method isGround (line 73) | @Override
    method applySubstitution (line 86) | @Override
    method normalize (line 97) | @Override
    method varSet (line 117) | @Override
    method updateVarCounts (line 124) | @Override
    method getId (line 131) | @Override
    method accept (line 136) | @Override
    method accept (line 141) | @Override
    method toString (line 146) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/FunctionCallFactory.java
  class FunctionCallFactory (line 40) | public final class FunctionCallFactory {
    method FunctionCallFactory (line 51) | public FunctionCallFactory(FunctionDefManager defManager) {
    method make (line 55) | public FunctionCall make(FunctionSymbol sym, Term[] args) {
    method getDefManager (line 70) | public FunctionDefManager getDefManager() {
    method clearMemoCache (line 74) | public void clearMemoCache() {
    class FunctionCall (line 78) | public class FunctionCall extends AbstractTerm implements Functor<Func...
      method FunctionCall (line 84) | private FunctionCall(FunctionSymbol sym, Term[] args) {
      method getSymbol (line 94) | @Override
      method getArgs (line 99) | @Override
      method copyWithNewArgs (line 104) | @Override
      method containsUnevaluatedTerm (line 109) | @Override
      method applySubstitution (line 114) | @Override
      method isGround (line 127) | @Override
      method toString (line 132) | @Override
      method normalize (line 137) | @Override
      method hasSideEffects (line 173) | private boolean hasSideEffects() {
      method computeWithMemoization (line 180) | private Term computeWithMemoization(Term[] newArgs) throws Evaluatio...
      method computeWithoutMemoization (line 198) | private Term computeWithoutMemoization(Term[] newArgs) throws Evalua...
      method getFactory (line 211) | public FunctionCallFactory getFactory() {
      method accept (line 215) | @Override
      method accept (line 220) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Functor.java
  type Functor (line 26) | public interface Functor<S extends Symbol> extends Term {
    method getSymbol (line 28) | S getSymbol();
    method getArgs (line 30) | Term[] getArgs();
    method copyWithNewArgs (line 32) | Term copyWithNewArgs(Term[] args);
    method varSet (line 34) | @Override
    method updateVarCounts (line 43) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/I32.java
  class I32 (line 33) | public class I32 extends AbstractTerm implements Primitive<Integer>, Smt...
    method I32 (line 38) | private I32(int val) {
    method make (line 42) | public static I32 make(int val) {
    method getVal (line 46) | @Override
    method toString (line 51) | @Override
    method substSolverTerms (line 56) | @Override
    method toSmtLib (line 61) | @Override
    method getType (line 66) | @Override
    method freeVars (line 71) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/I64.java
  class I64 (line 33) | public class I64 extends AbstractTerm implements Primitive<Long>, SmtLib...
    method I64 (line 38) | private I64(long val) {
    method make (line 42) | public static I64 make(long val) {
    method getVal (line 46) | @Override
    method toString (line 51) | @Override
    method substSolverTerms (line 56) | @Override
    method toSmtLib (line 61) | @Override
    method getType (line 66) | @Override
    method freeVars (line 71) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/LetFunExpr.java
  class LetFunExpr (line 32) | public class LetFunExpr implements Expr {
    method LetFunExpr (line 37) | private LetFunExpr(Set<NestedFunctionDef> defs, Term letBody) {
    method make (line 46) | public static LetFunExpr make(Set<NestedFunctionDef> defs, Term letBod...
    method getDefs (line 50) | public Set<NestedFunctionDef> getDefs() {
    method getLetBody (line 54) | public Term getLetBody() {
    method isGround (line 58) | @Override
    method applySubstitution (line 68) | @Override
    method normalize (line 77) | @Override
    method varSet (line 82) | @Override
    method updateVarCounts (line 91) | @Override
    method getId (line 96) | @Override
    method accept (line 101) | @Override
    method accept (line 106) | @Override
    method hashCode (line 111) | @Override
    method equals (line 120) | @Override
    method toString (line 135) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Literal.java
  type Literal (line 22) | public interface Literal {
    method getArgs (line 24) | Term[] getArgs();

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/MatchClause.java
  class MatchClause (line 31) | public class MatchClause {
    method make (line 36) | public static MatchClause make(Term lhs, Term rhs) {
    method checkForRepeatVariables (line 49) | private static boolean checkForRepeatVariables(Term pat) {
    method visit (line 56) | @Override
    method visit (line 64) | @Override
    method visit (line 73) | @Override
    method visit (line 78) | @Override
    method MatchClause (line 84) | MatchClause(Term lhs, Term rhs) {
    method tryMatch (line 89) | public boolean tryMatch(Term t, Substitution s) {
    method getLhs (line 119) | public Term getLhs() {
    method getRhs (line 123) | public Term getRhs() {
    method hashCode (line 127) | @Override
    method equals (line 136) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/MatchExpr.java
  class MatchExpr (line 36) | public class MatchExpr extends AbstractTerm implements Expr, Iterable<Ma...
    method make (line 42) | public static MatchExpr make(Term matchee, List<MatchClause> match) {
    method MatchExpr (line 46) | MatchExpr(Term matchee, List<MatchClause> match) {
    method getMatchee (line 63) | public Term getMatchee() {
    method getClauses (line 67) | public List<MatchClause> getClauses() {
    method accept (line 71) | @Override
    method normalize (line 76) | @Override
    method accept (line 98) | @Override
    method applySubstitution (line 103) | @Override
    method toString (line 125) | @Override
    method hashCode (line 135) | @Override
    method equals (line 144) | @Override
    method isGround (line 159) | @Override
    method varSet (line 164) | @Override
    method iterator (line 176) | @Override
    method updateVarCounts (line 181) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Model.java
  class Model (line 30) | public class Model extends AbstractTerm implements Primitive<Map<SolverV...
    method Model (line 36) | private Model(Map<SolverVariable, Term> m) {
    method make (line 40) | public static Model make(Map<SolverVariable, Term> m) {
    method getVal (line 44) | @Override
    method getType (line 49) | @Override
    method toString (line 54) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/NestedFunctionDef.java
  class NestedFunctionDef (line 29) | public class NestedFunctionDef {
    method NestedFunctionDef (line 35) | private NestedFunctionDef(FunctionSymbol sym, List<Var> params, Term b...
    method make (line 46) | public static NestedFunctionDef make(FunctionSymbol sym, List<Var> par...
    method applySubstitution (line 50) | public NestedFunctionDef applySubstitution(Substitution s) {
    method freshen (line 60) | public NestedFunctionDef freshen() {
    method getSymbol (line 71) | public FunctionSymbol getSymbol() {
    method getParams (line 75) | public List<Var> getParams() {
    method getBody (line 79) | public Term getBody() {
    method hashCode (line 83) | @Override
    method equals (line 92) | @Override
    method toString (line 107) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/OpaqueSet.java
  class OpaqueSet (line 35) | public class OpaqueSet extends AbstractTerm implements Primitive<Set<Ter...
    method OpaqueSet (line 39) | private OpaqueSet(PSet<Term> s) {
    method empty (line 52) | public static OpaqueSet empty() {
    method singleton (line 56) | public static OpaqueSet singleton(Term t) {
    method fromCollection (line 60) | public static OpaqueSet fromCollection(Collection<Term> c) {
    method make (line 68) | private static OpaqueSet make(PSet<Term> s) {
    method getCollection (line 72) | public Collection<Term> getCollection() {
    method member (line 76) | public boolean member(Term t) {
    method plus (line 80) | public OpaqueSet plus(Term t) {
    method minus (line 84) | public OpaqueSet minus(Term t) {
    method union (line 88) | public OpaqueSet union(OpaqueSet other) {
    method diff (line 92) | public OpaqueSet diff(OpaqueSet other) {
    method size (line 96) | public int size() {
    method isEmpty (line 100) | public boolean isEmpty() {
    method choose (line 104) | public Pair<Term, OpaqueSet> choose() {
    method containsAll (line 112) | public boolean containsAll(OpaqueSet other) {
    method getVal (line 116) | @Override
    method getType (line 121) | @Override
    method toString (line 126) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Primitive.java
  type Primitive (line 29) | public interface Primitive<T> extends Term {
    method getVal (line 31) | T getVal();
    method accept (line 33) | @Override
    method accept (line 38) | @Override
    method containsUnevaluatedTerm (line 43) | @Override
    method applySubstitution (line 48) | @Override
    method normalize (line 53) | @Override
    method isGround (line 58) | @Override
    method getType (line 63) | Type getType();
    method varSet (line 65) | @Override
    method updateVarCounts (line 70) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Program.java
  type Program (line 30) | public interface Program<Q extends Literal, R extends Rule<Q, ?>> {
    method getFunctionSymbols (line 32) | Set<FunctionSymbol> getFunctionSymbols();
    method getFactSymbols (line 34) | Set<RelationSymbol> getFactSymbols();
    method getRuleSymbols (line 36) | Set<RelationSymbol> getRuleSymbols();
    method getDef (line 38) | FunctionDef getDef(FunctionSymbol sym);
    method getFacts (line 40) | Set<Term[]> getFacts(RelationSymbol sym);
    method getRules (line 42) | Set<R> getRules(RelationSymbol sym);
    method getSymbolManager (line 44) | SymbolManager getSymbolManager();
    method hasQuery (line 46) | boolean hasQuery();
    method getQuery (line 48) | Q getQuery();
    method getFunctionCallFactory (line 50) | FunctionCallFactory getFunctionCallFactory();
    method getUninterpretedFunctionSymbols (line 52) | Set<ConstructorSymbol> getUninterpretedFunctionSymbols();
    method getTypeSymbols (line 54) | Set<TypeSymbol> getTypeSymbols();

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Rule.java
  type Rule (line 26) | public interface Rule<H extends Literal, B extends Literal> extends Iter...
    method getHead (line 28) | H getHead();
    method getBodySize (line 30) | int getBodySize();
    method getBody (line 32) | B getBody(int idx);
    method countVariables (line 34) | default Map<Var, Integer> countVariables() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/SmtLibTerm.java
  type SmtLibTerm (line 27) | public interface SmtLibTerm extends Term {
    method toSmtLib (line 29) | void toSmtLib(SmtLibShim shim);
    method substSolverTerms (line 31) | SmtLibTerm substSolverTerms(PMap<SolverVariable, SmtLibTerm> subst);
    method freeVars (line 33) | Set<SolverVariable> freeVars();

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/StringTerm.java
  class StringTerm (line 33) | public class StringTerm extends AbstractTerm implements Primitive<String...
    method StringTerm (line 38) | private StringTerm(String val) {
    method make (line 42) | public static StringTerm make(String val) {
    method getVal (line 46) | @Override
    method toString (line 51) | @Override
    method substSolverTerms (line 56) | @Override
    method toSmtLib (line 61) | @Override
    method getType (line 67) | @Override
    method freeVars (line 72) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Term.java
  type Term (line 30) | public interface Term {
    method accept (line 32) | <I, O> O accept(TermVisitor<I, O> v, I in);
    method accept (line 34) | <I, O, E extends Throwable> O accept(TermVisitorExn<I, O, E> v, I in) ...
    method isGround (line 36) | boolean isGround();
    method containsUnevaluatedTerm (line 38) | boolean containsUnevaluatedTerm();
    method applySubstitution (line 40) | Term applySubstitution(Substitution s);
    method normalize (line 42) | Term normalize(Substitution s) throws EvaluationException;
    method varSet (line 44) | void varSet(Set<Var> acc);
    method varSet (line 46) | default Set<Var> varSet() {
    method updateVarCounts (line 52) | void updateVarCounts(Map<Var, Integer> counts);
    method getId (line 54) | int getId();

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Terms.java
  class Terms (line 35) | public final class Terms {
    method Terms (line 37) | private Terms() {
    method emptyArray (line 43) | public static Term[] emptyArray() {
    method singletonArray (line 47) | public static Term[] singletonArray(Term t) {
    method map (line 51) | public static Term[] map(Term[] ts, Function<Term, Term> f) {
    method mapExn (line 59) | public static <E extends Exception> Term[] mapExn(Term[] ts, Exception...
    method normalize (line 68) | public static Term[] normalize(Term[] ts, Substitution s) throws Evalu...
    method isGround (line 76) | public static boolean isGround(Term t, Set<Var> boundVars) {
    method getNonBindingVarInstances (line 80) | public static Set<Var> getNonBindingVarInstances(Term t) {
    method getBindingVarInstances (line 113) | public static Set<Var> getBindingVarInstances(Term t) {
    type TermVisitor (line 146) | public static interface TermVisitor<I, O> {
      method visit (line 148) | O visit(Var t, I in);
      method visit (line 150) | O visit(Constructor c, I in);
      method visit (line 152) | O visit(Primitive<?> p, I in);
      method visit (line 154) | O visit(Expr e, I in);
    type TermVisitorExn (line 157) | public static interface TermVisitorExn<I, O, E extends Throwable> {
      method visit (line 159) | O visit(Var x, I in) throws E;
      method visit (line 161) | O visit(Constructor c, I in) throws E;
      method visit (line 163) | O visit(Primitive<?> p, I in) throws E;
      method visit (line 165) | O visit(Expr e, I in) throws E;
    class DummyTerm (line 172) | private static class DummyTerm implements Term {
      method DummyTerm (line 176) | public DummyTerm(int id) {
      method accept (line 180) | @Override
      method accept (line 185) | @Override
      method isGround (line 190) | @Override
      method containsUnevaluatedTerm (line 195) | @Override
      method applySubstitution (line 200) | @Override
      method normalize (line 205) | @Override
      method varSet (line 210) | @Override
      method getId (line 215) | @Override
      method updateVarCounts (line 220) | @Override
      method toString (line 225) | @Override
    method makeDummyTerm (line 231) | public static Term makeDummyTerm(int id) {
    method nextId (line 237) | public static int nextId() {
    method termToTermList (line 241) | @SuppressWarnings("unchecked")
    method termListToTerm (line 254) | public static <T extends Term> Term termListToTerm(List<T> l) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/UnificationPredicate.java
  class UnificationPredicate (line 27) | public class UnificationPredicate implements ComplexLiteral {
    method make (line 32) | public static UnificationPredicate make(Term lhs, Term rhs, boolean ne...
    method UnificationPredicate (line 36) | private UnificationPredicate(Term[] args, boolean negated) {
    method getArgs (line 41) | @Override
    method getLhs (line 46) | public Term getLhs() {
    method getRhs (line 50) | public Term getRhs() {
    method applySubstitution (line 54) | @Override
    method isNegated (line 61) | @Override
    method toString (line 66) | @Override
    method accept (line 71) | @Override
    method accept (line 76) | @Override
    method hashCode (line 82) | @Override
    method equals (line 91) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/UserPredicate.java
  class UserPredicate (line 28) | public class UserPredicate implements ComplexLiteral {
    method make (line 34) | public static UserPredicate make(RelationSymbol symbol, Term[] args, b...
    method UserPredicate (line 38) | private UserPredicate(RelationSymbol symbol, Term[] args, boolean nega...
    method getSymbol (line 44) | public RelationSymbol getSymbol() {
    method getArgs (line 48) | @Override
    method isNegated (line 53) | @Override
    method applySubstitution (line 58) | @Override
    method hashCode (line 67) | @Override
    method equals (line 77) | @Override
    method toString (line 91) | @Override
    method accept (line 112) | @Override
    method accept (line 117) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/ast/Var.java
  class Var (line 31) | public class Var extends AbstractTerm {
    method Var (line 37) | protected Var(String name) {
    method fresh (line 41) | public static Var fresh(String name) {
    method fresh (line 45) | public static Var fresh() {
    method isUnderscore (line 49) | public boolean isUnderscore() {
    method getName (line 53) | public String getName() {
    method toString (line 57) | @Override
    method accept (line 62) | @Override
    method accept (line 67) | @Override
    method isGround (line 72) | @Override
    method containsUnevaluatedTerm (line 77) | @Override
    method applySubstitution (line 82) | @Override
    method normalize (line 90) | @Override
    method varSet (line 96) | @Override
    method updateVarCounts (line 101) | @Override
    method makeHole (line 109) | public static Var makeHole() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/CodeGen.java
  class CodeGen (line 47) | public class CodeGen {
    method CodeGen (line 52) | public CodeGen(BasicProgram prog, File outDir) {
    method go (line 57) | public void go() throws IOException, URISyntaxException, CodeGenExcept...
    method copy (line 95) | private void copy(String name) throws IOException {
    method copySrc (line 103) | private void copySrc(String name) throws IOException {
    method main (line 107) | public static void main(String[] args) throws Exception {
    method main (line 114) | public static void main(File file, File outDir) throws Exception {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/CodeGenContext.java
  class CodeGenContext (line 37) | public class CodeGenContext {
    method CodeGenContext (line 51) | public CodeGenContext(BasicProgram prog) {
    method getProgram (line 56) | public BasicProgram getProgram() {
    method getConstructorSymbols (line 60) | public Set<ConstructorSymbol> getConstructorSymbols() {
    method lookupUnqualifiedRepr (line 64) | public synchronized String lookupUnqualifiedRepr(ConstructorSymbol sym) {
    method lookupRepr (line 74) | public synchronized String lookupRepr(ConstructorSymbol sym) {
    method lookupRepr (line 78) | public synchronized String lookupRepr(FunctionSymbol sym) {
    method lookupRepr (line 84) | public synchronized String lookupRepr(RelationSymbol sym) {
    method lookupRel (line 90) | public synchronized RelationSymbol lookupRel(String repr) {
    method register (line 94) | public synchronized void register(FunctionSymbol sym, String repr) {
    method register (line 99) | public synchronized void register(SIntListType type) {
    method getSouffleTypes (line 103) | public synchronized Set<SIntListType> getSouffleTypes() {
    method newId (line 107) | public String newId(String prefix) {
    method lookupOrCreateFunctorName (line 111) | public synchronized String lookupOrCreateFunctorName(Term t) {
    method lookupOrCreateFunctorName (line 115) | public synchronized String lookupOrCreateFunctorName(ConstructorSymbol...
    method registerFunctorBody (line 119) | public void registerFunctorBody(String functor, SFunctorBody body) {
    method getFunctors (line 123) | public Set<Pair<String, SFunctorBody>> getFunctors() {
    method getCustomRelations (line 131) | public Set<Pair<String, Pair<Integer, SRuleMode>>> getCustomRelations() {
    method registerCustomRelation (line 137) | public void registerCustomRelation(String name, Integer arity, SRuleMo...
    class Worker (line 143) | private class Worker {
      method Worker (line 145) | public Worker() {}
      method go (line 147) | public void go() {
      method processTypes (line 154) | private void processTypes(Set<TypeSymbol> typeSymbols) {
      method processType (line 162) | private void processType(AlgebraicDataType type) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/CodeGenException.java
  class CodeGenException (line 22) | public class CodeGenException extends Exception {
    method CodeGenException (line 26) | public CodeGenException(String message) {
    method CodeGenException (line 30) | public CodeGenException(Exception cause) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/CodeGenUtil.java
  class CodeGenUtil (line 43) | public final class CodeGenUtil {
    method CodeGenUtil (line 45) | private CodeGenUtil() {
    method printIndent (line 49) | public static void printIndent(PrintWriter out, int indent) {
    method print (line 55) | public static void print(Iterable<CppStmt> stmts, PrintWriter out, int...
    method printSeparated (line 61) | public static void printSeparated(Iterable<CppExpr> exprs, String sep,...
    method mkComplexTermLookup (line 70) | public static CppExpr mkComplexTermLookup(CppExpr base, int offset) {
    method copyOver (line 76) | public static void copyOver(BufferedReader in, PrintWriter out, int st...
    method mkName (line 83) | public static String mkName(Symbol sym) {
    method toString (line 103) | public static String toString(CppStmt stmt, int indent) {
    method inputSrcFile (line 109) | public static InputStream inputSrcFile(String file) {
    method outputSrcFile (line 117) | public static File outputSrcFile(File topDir, String file) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/DeltaFirstQueryPlanner.java
  class DeltaFirstQueryPlanner (line 30) | public class DeltaFirstQueryPlanner implements QueryPlanner {
    method DeltaFirstQueryPlanner (line 34) | public DeltaFirstQueryPlanner(CodeGenContext ctx) {
    method genPlan (line 38) | @Override
    method findDeltas (line 50) | private Pair<Integer, List<Integer>> findDeltas(SRule r, Stratum strat...
    method genPlanForDelta (line 69) | private int[] genPlanForDelta(int delta, int numAtoms) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/FuncsHpp.java
  class FuncsHpp (line 34) | public class FuncsHpp extends TemplateSrcFile {
    method FuncsHpp (line 36) | public FuncsHpp(CodeGenContext ctx) {
    method gen (line 40) | public void gen(BufferedReader br, PrintWriter out) throws IOException {
    class Worker (line 49) | private class Worker {
      method Worker (line 56) | public Worker(PrintWriter out) {
      method makeDeclarations (line 60) | private void makeDeclarations() {
      method declareFunction (line 81) | private void declareFunction(FunctionSymbol sym) {
      method registerBuiltInFunction (line 96) | private void registerBuiltInFunction(BuiltInFunctionSymbol sym) {
      method makeDefinitions (line 424) | private void makeDefinitions() {
      method makeDefinitionForUserDefinedFunc (line 437) | private void makeDefinitionForUserDefinedFunc(FunctionSymbol sym) {
      method makeDefinitionForPredFunc (line 485) | private void makeDefinitionForPredFunc(PredicateFunctionSymbol funcS...
      method mkArgsVec (line 532) | private CppExpr mkArgsVec(CppVar[] args) {
      method genRelationAggMono (line 540) | private Pair<CppStmt, CppExpr> genRelationAggMono(
      method genRelationAggPoly (line 548) | private Pair<CppStmt, CppExpr> genRelationAggPoly(
      method genRelationContains (line 569) | private Pair<CppStmt, CppExpr> genRelationContains(
      method numBound (line 583) | private int numBound(BindingType[] bindings) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/FunctorCodeGen.java
  class FunctorCodeGen (line 32) | public class FunctorCodeGen {
    method FunctorCodeGen (line 39) | public FunctorCodeGen(CodeGenContext ctx) {
    method emitFunctors (line 43) | public void emitFunctors(File directory) throws CodeGenException {
    method emitHeader (line 48) | private void emitHeader(File directory) throws CodeGenException {
    method emitSignature (line 67) | private Map<Var, CppVar> emitSignature(String functor, SFunctorBody bo...
    method emitSource (line 92) | private void emitSource(File directory) throws CodeGenException {
    class SourceWorker (line 108) | private class SourceWorker {
      method SourceWorker (line 112) | public SourceWorker(PrintWriter out_) {
      method emitFunctors (line 116) | public void emitFunctors() {
      method emitFunctor (line 123) | private void emitFunctor(String functor, SFunctorBody body) {
      method unpackParams (line 139) | private Pair<CppStmt, Map<Var, CppExpr>> unpackParams(Map<Var, CppVa...
      method genTermBody (line 152) | private Pair<CppStmt, CppExpr> genTermBody(Term t, Map<Var, CppExpr>...
      method genDtorBody (line 159) | private Pair<CppStmt, CppExpr> genDtorBody(SDestructorBody body, Map...

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/MainCpp.java
  class MainCpp (line 34) | public class MainCpp extends TemplateSrcFile {
    method MainCpp (line 36) | public MainCpp(CodeGenContext ctx) {
    method gen (line 40) | public void gen(BufferedReader br, PrintWriter out) throws IOException...
    class Worker (line 51) | private class Worker {
      method Worker (line 55) | public Worker(PrintWriter out) {
      method loadExternalEdbs (line 59) | public void loadExternalEdbs() {
      method loadExternalEdbs (line 67) | public void loadExternalEdbs(RelationSymbol sym) {
      method loadStaticFacts (line 76) | public void loadStaticFacts() throws CodeGenException {
      method loadStaticFact (line 86) | public void loadStaticFact(RelationSymbol sym, Term[] tup) throws Co...
      method printIdbsToDisk (line 105) | public void printIdbsToDisk() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/MatchCodeGen.java
  class MatchCodeGen (line 51) | public class MatchCodeGen {
    method MatchCodeGen (line 56) | public MatchCodeGen(CodeGenContext ctx) {
    method gen (line 69) | public Pair<CppStmt, CppExpr> gen(MatchExpr match, Map<Var, CppExpr> e...
    class Worker (line 83) | private class Worker {
      method Worker (line 94) | public Worker(Map<Var, CppExpr> env) {
      method go (line 104) | public Pair<CppStmt, CppExpr> go(MatchExpr match) {
      method optimizeIfExpr (line 138) | private Pair<CppStmt, CppExpr> optimizeIfExpr(MatchExpr match) {
      method optimizeIfExpr (line 165) | private Pair<CppStmt, CppExpr> optimizeIfExpr(
      method preprocess (line 195) | private List<Pair<Term, Term>> preprocess(List<MatchClause> clauses) {
      method renameVars (line 228) | private Pair<Term, Set<Var>> renameVars(Term t, Substitution s) {
      method processTree (line 278) | private CppStmt processTree(CppExpr scrutinee, PatternMatchTree tree) {
      class TreeProcessor (line 283) | private class TreeProcessor {
        method TreeProcessor (line 288) | public TreeProcessor(CppExpr scrutinee, PatternMatchTree tree) {
        method go (line 299) | public CppStmt go() {
        method go (line 309) | private CppStmt go(Node node, HashPMap<SymbolicTerm, CppExpr> symM...
        method go (line 370) | private CppStmt go(

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/NopQueryPlanner.java
  class NopQueryPlanner (line 27) | public class NopQueryPlanner implements QueryPlanner {
    method genPlan (line 29) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/PatternMatchTree.java
  class PatternMatchTree (line 40) | public class PatternMatchTree {
    method PatternMatchTree (line 50) | public PatternMatchTree(List<Pair<Term, Term>> clauses) {
    method getRoot (line 60) | public Node getRoot() {
    method getOutgoingEdges (line 71) | public Iterable<Pair<Edge<?>, Node>> getOutgoingEdges(Node node) {
    method toString (line 75) | @Override
    method build (line 90) | private Node build(PatternMatchingComputation k) {
    type SymbolicTerm (line 107) | public static interface SymbolicTerm {}
    type BaseSymbolicTerm (line 110) | public static enum BaseSymbolicTerm implements SymbolicTerm {
      method toString (line 113) | @Override
    class DerivedSymbolicTerm (line 123) | public static class DerivedSymbolicTerm implements SymbolicTerm {
      method DerivedSymbolicTerm (line 128) | private DerivedSymbolicTerm(SymbolicTerm base, int index) {
      method getBase (line 133) | public SymbolicTerm getBase() {
      method getIndex (line 137) | public int getIndex() {
      method toString (line 141) | @Override
    class PatternMatchingComputation (line 151) | private static class PatternMatchingComputation {
      method PatternMatchingComputation (line 169) | private PatternMatchingComputation(
      method mk (line 181) | public static PatternMatchingComputation mk(List<Pair<Term, Term>> c...
      method stepComputation (line 205) | public Iterable<Pair<Edge<?>, PatternMatchingComputation>> stepCompu...
      method step (line 256) | private static Edge<?> step(Deque<Term> d) {
      method getCurrentSymbolicTerm (line 278) | public SymbolicTerm getCurrentSymbolicTerm() {
      method isFinished (line 288) | public boolean isFinished() {
      method getFinalTerm (line 297) | public Term getFinalTerm() {
      method toString (line 302) | @Override
    method visit (line 319) | @Override
    method visit (line 324) | @Override
    method visit (line 329) | @Override
    method visit (line 334) | @Override
    type Node (line 342) | public static interface Node {
      method accept (line 344) | <I, O> O accept(NodeVisitor<I, O> visitor, I in);
    type NodeVisitor (line 347) | public static interface NodeVisitor<I, O> {
      method visit (line 349) | O visit(InternalNode node, I in);
      method visit (line 351) | O visit(Leaf node, I in);
    class InternalNode (line 355) | public static class InternalNode implements Node {
      method InternalNode (line 362) | public InternalNode(SymbolicTerm symbolicTerm) {
      method getSymbolicTerm (line 366) | public SymbolicTerm getSymbolicTerm() {
      method accept (line 370) | @Override
      method toString (line 375) | @Override
    class Leaf (line 385) | public static class Leaf implements Node {
      method Leaf (line 389) | public Leaf(Term term) {
      method getTerm (line 393) | public Term getTerm() {
      method accept (line 397) | @Override
      method toString (line 402) | @Override
    type Edge (line 415) | public static interface Edge<T> {
      method getLabel (line 417) | T getLabel();
      method accept (line 419) | <I, O> O accept(EdgeVisitor<I, O> visitor, I in);
    type EdgeVisitor (line 422) | public static interface EdgeVisitor<I, O> {
      method visit (line 424) | O visit(VarEdge e, I in);
      method visit (line 426) | O visit(PrimEdge e, I in);
      method visit (line 428) | O visit(CtorEdge e, I in);
    class AbstractEdge (line 431) | private abstract static class AbstractEdge<T> implements Edge<T> {
      method AbstractEdge (line 435) | public AbstractEdge(T label) {
      method getLabel (line 439) | @Override
      method hashCode (line 444) | @Override
      method equals (line 452) | @Override
    class VarEdge (line 467) | public static class VarEdge extends AbstractEdge<Var> {
      method VarEdge (line 469) | public VarEdge(Var label) {
      method accept (line 473) | @Override
      method toString (line 478) | @Override
    class PrimEdge (line 485) | public static class PrimEdge extends AbstractEdge<Primitive<?>> {
      method PrimEdge (line 487) | public PrimEdge(Primitive<?> label) {
      method accept (line 491) | @Override
      method toString (line 496) | @Override
    class CtorEdge (line 503) | public static class CtorEdge extends AbstractEdge<ConstructorSymbol> {
      method CtorEdge (line 505) | public CtorEdge(ConstructorSymbol label) {
      method accept (line 509) | @Override
      method toString (line 514) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/QueryPlanner.java
  type QueryPlanner (line 27) | public interface QueryPlanner {
    method genPlan (line 28) | List<Pair<Integer, int[]>> genPlan(SRule r, Stratum stratum);

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/RuleTranslator.java
  class RuleTranslator (line 66) | public class RuleTranslator {
    method RuleTranslator (line 73) | public RuleTranslator(CodeGenContext ctx, QueryPlanner queryPlanner) {
    method translate (line 78) | public Pair<List<SRule>, List<Stratum>> translate(BasicProgram prog) t...
    method checkStratification (line 97) | private List<Stratum> checkStratification(BasicProgram prog) throws Co...
    class Worker (line 113) | private class Worker {
      method Worker (line 120) | public Worker(BasicProgram prog) {
      method translate (line 124) | private List<SRule> translate(BasicRule br) throws CodeGenException {
      method addVars (line 189) | void addVars(Collection<SLit> lits, Set<SVar> vars) {
      method liveVarsByBody (line 195) | List<Set<SVar>> liveVarsByBody(SLit head, List<List<SLit>> bodies) {
      method newSmtSupAtom (line 208) | private SAtom newSmtSupAtom(Collection<SVar> vars) {
      method translate (line 214) | private List<SLit> translate(SimpleLiteral lit) {
      method handleNegatedPredicate (line 281) | private SLit handleNegatedPredicate(SimplePredicate predicate, List<...
      method createProjectionSymbol (line 307) | private String createProjectionSymbol(RelationSymbol sym, List<Boole...
      method liftToFunctor (line 317) | private SFunctorCall liftToFunctor(Term t) {
      method translate (line 325) | private STerm translate(Term t) {
      method createProjectionRules (line 351) | List<SRule> createProjectionRules() {
      method createProjection (line 359) | private SRule createProjection(RelationSymbol sym, List<Boolean> pro...
      method createCheckRule (line 376) | public SRule createCheckRule() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/SmtParserCpp.java
  class SmtParserCpp (line 53) | public class SmtParserCpp extends TemplateSrcFile {
    method SmtParserCpp (line 55) | public SmtParserCpp(CodeGenContext ctx) {
    method gen (line 59) | @Override
    class Worker (line 71) | private class Worker {
      method Worker (line 78) | public Worker(PrintWriter out) {
      method outputShouldRecord (line 88) | private void outputShouldRecord() throws CodeGenException {
      method outputParseFuncs (line 104) | private void outputParseFuncs() {
      method genParseFunc (line 121) | private String genParseFunc(AlgebraicDataType ty) {
      method genConstructorCase (line 145) | private Pair<CppExpr, CppStmt> genConstructorCase(CppExpr scrutinee,...
      method outputParseTerm (line 164) | private void outputParseTerm() {
      method getSmtVarType (line 172) | private AlgebraicDataType getSmtVarType(ConstructorSymbol sym) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/SmtShimCpp.java
  class SmtShimCpp (line 38) | public class SmtShimCpp extends TemplateSrcFile {
    method SmtShimCpp (line 40) | public SmtShimCpp(CodeGenContext ctx) {
    method gen (line 44) | public void gen(BufferedReader br, PrintWriter out) throws IOException {
    class Worker (line 59) | private class Worker {
      method Worker (line 64) | public Worker(PrintWriter out) {
      method isVarSymbol (line 73) | private boolean isVarSymbol(ConstructorSymbol sym) {
      method copyDeclarations (line 79) | public void copyDeclarations() {
      method genSolverVarCases (line 90) | public void genSolverVarCases() {
      method genSerializationCases (line 100) | public void genSerializationCases() {
      method genSerializationCase (line 106) | private void genSerializationCase(ConstructorSymbol sym) {
      method genSerializationCaseBody (line 117) | private CppStmt genSerializationCaseBody(ConstructorSymbol sym) {
      method genBuiltInConstructorSymbolCase (line 127) | private CppStmt genBuiltInConstructorSymbolCase(BuiltInConstructorSy...
      method index (line 246) | private int index(ParameterizedConstructorSymbol sym, int i) {
      method mkCall (line 250) | private CppStmt mkCall(String func) {
      method genParameterizedConstructorSymbolCase (line 254) | private CppStmt genParameterizedConstructorSymbolCase(ParameterizedC...
      method genSerializeOp (line 354) | private CppStmt genSerializeOp(String op) {
      method genSerializeBitString (line 360) | private CppStmt genSerializeBitString(int n, boolean big) {
      method genSerializeBvToBv (line 369) | private CppStmt genSerializeBvToBv(int from, int to, boolean signed) {
      method genSerializeFpToBv (line 374) | private CppStmt genSerializeFpToBv(int width, boolean signed) {
      method genSerializeFp (line 379) | private CppStmt genSerializeFp(int e, int s, boolean big) {
      method genSerializeInt (line 386) | private CppStmt genSerializeInt(boolean big) {
      method genSerializeQuantifier (line 392) | private CppStmt genSerializeQuantifier(boolean exists) {
      method genNeedsTypeAnnotationCases (line 397) | public void genNeedsTypeAnnotationCases() {
      method genSymbolSerializationCases (line 410) | public void genSymbolSerializationCases() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/SouffleCodeGen.java
  class SouffleCodeGen (line 36) | public class SouffleCodeGen {
    method SouffleCodeGen (line 44) | public SouffleCodeGen(CodeGenContext ctx) {
    method gen (line 48) | public void gen(File directory) throws CodeGenException, IOException {
    method chooseQueryPlanner (line 61) | private QueryPlanner chooseQueryPlanner() throws CodeGenException {
    method emitDlFile (line 73) | private void emitDlFile(File dlFile, List<SRule> rules) throws CodeGen...
    method genRuleForRetainingInputRelations (line 93) | SRule genRuleForRetainingInputRelations() {
    method genRulesForEnforcingStratification (line 103) | private List<SRule> genRulesForEnforcingStratification(List<Stratum> s...
    method makeAtomWithDummyArgs (line 119) | private SAtom makeAtomWithDummyArgs(RelationSymbol sym, boolean negate...
    class Worker (line 127) | private class Worker {
      method Worker (line 131) | public Worker(PrintWriter writer) {
      method declareTypes (line 135) | public void declareTypes() {
      method declareRelations (line 144) | public void declareRelations() {
      method declareRelation (line 156) | private void declareRelation(String name, int arity, SRuleMode mode) {
      method declareRelation (line 182) | private void declareRelation(RelationSymbol sym, SRuleMode mode) {
      method declareFunctors (line 186) | public void declareFunctors() {
      method declareFunctor (line 195) | private void declareFunctor(String name, SFunctorBody body) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/SymbolCpp.java
  class SymbolCpp (line 30) | public class SymbolCpp extends TemplateSrcFile {
    method SymbolCpp (line 32) | public SymbolCpp(CodeGenContext ctx) {
    method gen (line 36) | public void gen(BufferedReader br, PrintWriter out) throws IOException {
    class Worker (line 47) | private class Worker {
      method Worker (line 52) | public Worker(PrintWriter out) {
      method defineSerialization (line 56) | void defineSerialization() {
      method initializeSymbolTable (line 66) | void initializeSymbolTable() {
      method defineTupleLookup (line 75) | void defineTupleLookup() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/SymbolHpp.java
  class SymbolHpp (line 28) | public class SymbolHpp extends TemplateSrcFile {
    method SymbolHpp (line 30) | public SymbolHpp(CodeGenContext ctx) {
    method gen (line 34) | public void gen(BufferedReader br, PrintWriter out) throws IOException {
    class Worker (line 43) | private class Worker {
      method Worker (line 48) | public Worker(PrintWriter out) {
      method declareSymbols (line 52) | void declareSymbols() {
      method defineArity (line 59) | void defineArity() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/TemplateSrcFile.java
  class TemplateSrcFile (line 24) | public abstract class TemplateSrcFile {
    method TemplateSrcFile (line 29) | public TemplateSrcFile(String name, CodeGenContext ctx) {
    method gen (line 34) | void gen(File outDir) throws IOException, CodeGenException {
    method gen (line 44) | abstract void gen(BufferedReader br, PrintWriter out) throws IOExcepti...

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/TermCodeGen.java
  class TermCodeGen (line 41) | public class TermCodeGen {
    method TermCodeGen (line 45) | public TermCodeGen(CodeGenContext ctx) {
    method mkBool (line 49) | public CppExpr mkBool(CppExpr bool) {
    method mkComplex (line 70) | public Pair<CppStmt, CppExpr> mkComplex(ConstructorSymbol sym, List<Cp...
    method mkComplex (line 86) | public Pair<CppStmt, CppExpr> mkComplex(ConstructorSymbol sym, CppExpr...
    method mkComplex (line 100) | public CppExpr mkComplex(List<CppStmt> acc, ConstructorSymbol sym, Cpp...
    method mkComplex (line 116) | public CppExpr mkComplex(List<CppStmt> acc, ConstructorSymbol sym, Lis...
    method gen (line 131) | public Pair<CppStmt, CppExpr> gen(Term t, Map<Var, CppExpr> env) {
    method gen (line 147) | public CppExpr gen(List<CppStmt> acc, Term t, Map<Var, CppExpr> env) {
    method gen (line 161) | public List<CppExpr> gen(List<CppStmt> acc, List<Term> ts, Map<Var, Cp...
    method gen (line 178) | public Pair<CppStmt, List<CppExpr>> gen(List<Term> ts, Map<Var, CppExp...
    class Worker (line 184) | private class Worker {
      method Worker (line 190) | public Worker(List<CppStmt> acc, Map<Var, CppExpr> env) {
      method go (line 195) | public CppExpr go(Term t) {
      method visit (line 202) | @Override
      method visit (line 208) | @Override
      method visit (line 222) | @Override
      method visit (line 227) | @Override
      method visit (line 236) | @Override
      method visit (line 243) | @Override
      method visit (line 252) | @Override
      method visit (line 257) | @Override
    method genIntizeTerm (line 270) | public static CppExpr genIntizeTerm(CppExpr term) {
    method genUnintizeTerm (line 274) | public static CppExpr genUnintizeTerm(CppExpr id) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/TermCpp.java
  class TermCpp (line 29) | public class TermCpp extends TemplateSrcFile {
    method TermCpp (line 31) | public TermCpp(CodeGenContext ctx) {
    method gen (line 35) | public void gen(BufferedReader br, PrintWriter out) throws IOException {
    class Worker (line 44) | private class Worker {
      method Worker (line 49) | public Worker(PrintWriter out) {
      method declareExplicitTemplateInstantiations (line 53) | void declareExplicitTemplateInstantiations() {
      method declareMakeGenericCases (line 65) | void declareMakeGenericCases() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/TypeCodeGen.java
  class TypeCodeGen (line 39) | public class TypeCodeGen {
    method TypeCodeGen (line 43) | public TypeCodeGen(CodeGenContext ctx) {
    method gen (line 55) | public Pair<CppStmt, CppExpr> gen(Type type) {
    method gen (line 70) | public CppExpr gen(List<CppStmt> acc, Type type) {
    method gen (line 83) | public List<CppExpr> gen(List<CppStmt> acc, List<Type> types) {
    method gen (line 99) | public Pair<CppStmt, List<CppExpr>> gen(List<Type> types) {
    class Worker (line 105) | private class Worker {
      method Worker (line 111) | public Worker(List<CppStmt> acc, Map<TypeVar, CppExpr> env) {
      method go (line 116) | public CppExpr go(Type type) {
      method go (line 123) | private List<CppExpr> go(List<Type> types) {
      method go1 (line 131) | private CppExpr go1(FunctorType type) {
      method visit (line 141) | @Override
      method visit (line 154) | @Override
      method visit (line 168) | @Override
      method visit (line 173) | @Override
      method handleBuiltInType (line 179) | private CppExpr handleBuiltInType(AlgebraicDataType type) {
      method mkType (line 211) | private CppExpr mkType(String name) {
      method mkType (line 215) | private CppExpr mkType(String name, List<Type> args) {
      method mkVec (line 225) | private CppExpr mkVec(List<Type> args) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/TypeCpp.java
  class TypeCpp (line 36) | public class TypeCpp extends TemplateSrcFile {
    method TypeCpp (line 38) | public TypeCpp(CodeGenContext ctx) {
    method gen (line 42) | public void gen(BufferedReader br, PrintWriter out) throws IOException {
    class Worker (line 49) | private class Worker {
      method Worker (line 54) | public Worker(PrintWriter out) {
      method defineSymbolTypes (line 58) | public void defineSymbolTypes() {
      method defineSymbolType (line 64) | private void defineSymbolType(ConstructorSymbol sym) {
      method genCaseBody (line 70) | private CppStmt genCaseBody(ConstructorSymbol sym) {
      method simplify (line 78) | private FunctorType simplify(FunctorType ft) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppAccess.java
  class CppAccess (line 24) | public class CppAccess implements CppExpr {
    method CppAccess (line 30) | private CppAccess(CppExpr val, String field, boolean thruPtr) {
    method mk (line 36) | public static CppAccess mk(CppExpr val, String field) {
    method mkThruPtr (line 40) | public static CppAccess mkThruPtr(CppExpr val, String field) {
    method print (line 44) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppBaseTerm.java
  class CppBaseTerm (line 31) | public class CppBaseTerm implements CppExpr {
    method mk (line 35) | public static CppBaseTerm mk(Primitive<?> p) {
    method CppBaseTerm (line 39) | private CppBaseTerm(Primitive<?> p) {
    method print (line 43) | @Override
    method printMakeTerm (line 67) | void printMakeTerm(String type, String val, PrintWriter out) {
    method handleDouble (line 75) | public static String handleDouble(double d) {
    method handleFloat (line 87) | public static String handleFloat(float d) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppBinop.java
  class CppBinop (line 24) | public class CppBinop implements CppExpr {
    method CppBinop (line 30) | private CppBinop(CppExpr lhs, String op, CppExpr rhs) {
    method mk (line 36) | private static CppBinop mk(CppExpr lhs, String op, CppExpr rhs) {
    method mkOrUpdate (line 40) | public static CppBinop mkOrUpdate(CppExpr lhs, CppExpr rhs) {
    method mkLogAnd (line 44) | public static CppBinop mkLogAnd(CppExpr lhs, CppExpr rhs) {
    method mkNotEq (line 48) | public static CppBinop mkNotEq(CppExpr lhs, CppExpr rhs) {
    method mkLt (line 52) | public static CppBinop mkLt(CppExpr lhs, CppExpr rhs) {
    method mkAssign (line 56) | public static CppBinop mkAssign(CppExpr lhs, CppExpr rhs) {
    method mkEq (line 60) | public static CppExpr mkEq(CppExpr lhs, CppExpr rhs) {
    method mkShiftLeft (line 64) | public static CppExpr mkShiftLeft(CppExpr lhs, CppExpr rhs) {
    method print (line 68) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppBlock.java
  class CppBlock (line 25) | public class CppBlock implements CppStmt {
    method CppBlock (line 29) | private CppBlock(CppStmt stmt) {
    method mk (line 33) | public static CppBlock mk(CppStmt stmt) {
    method println (line 37) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppCast.java
  class CppCast (line 24) | public class CppCast implements CppExpr {
    method CppCast (line 30) | private CppCast(String castName, String type, CppExpr expr) {
    method mkReinterpret (line 36) | public static CppCast mkReinterpret(String type, CppExpr expr) {
    method print (line 40) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppConst.java
  class CppConst (line 24) | public class CppConst<T> implements CppExpr {
    method CppConst (line 28) | private CppConst(T val) {
    method mkTrue (line 32) | public static CppConst<Boolean> mkTrue() {
    method mkFalse (line 36) | public static CppConst<Boolean> mkFalse() {
    method mkInt (line 40) | public static CppConst<Integer> mkInt(int i) {
    method mkString (line 44) | public static CppConst<String> mkString(String s) {
    method print (line 48) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppCtor.java
  class CppCtor (line 27) | public class CppCtor implements CppStmt {
    method CppCtor (line 34) | private CppCtor(String type, String var, List<CppExpr> args, boolean i...
    method mk (line 41) | public static CppCtor mk(String type, String var, List<CppExpr> args) {
    method mk (line 45) | public static CppCtor mk(String type, String var, CppExpr... args) {
    method mkInitializer (line 49) | public static CppCtor mkInitializer(String type, String var, List<CppE...
    method mkInitializer (line 53) | public static CppCtor mkInitializer(String type, String var, CppExpr.....
    method println (line 57) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppDecl.java
  class CppDecl (line 25) | public class CppDecl implements CppStmt {
    method CppDecl (line 31) | private CppDecl(String type, String var, CppExpr val) {
    method mk (line 37) | public static CppDecl mk(String var, CppExpr val) {
    method mkRef (line 41) | public static CppDecl mkRef(String var, CppExpr val) {
    method println (line 45) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppExpr.java
  type CppExpr (line 25) | public interface CppExpr {
    method print (line 27) | void print(PrintWriter out);
    method toStmt (line 29) | default CppStmt toStmt() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppExprFromString.java
  class CppExprFromString (line 24) | public class CppExprFromString implements CppExpr {
    method CppExprFromString (line 28) | private CppExprFromString(String s) {
    method mk (line 32) | public static CppExprFromString mk(String s) {
    method print (line 36) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppFor.java
  class CppFor (line 25) | public class CppFor implements CppStmt {
    method CppFor (line 34) | private CppFor(
    method mk (line 44) | public static CppFor mk(String var, CppExpr init, CppExpr guard, CppEx...
    method mkParallel (line 48) | public static CppFor mkParallel(
    method println (line 53) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppForEach.java
  class CppForEach (line 25) | public class CppForEach implements CppStmt {
    method CppForEach (line 31) | private CppForEach(String var, CppExpr val, CppStmt body) {
    method mk (line 37) | public static CppForEach mk(String var, CppExpr val, CppStmt body) {
    method println (line 41) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppFuncCall.java
  class CppFuncCall (line 27) | public class CppFuncCall implements CppExpr {
    method CppFuncCall (line 32) | private CppFuncCall(String func, List<CppExpr> args) {
    method mk (line 37) | public static CppFuncCall mk(String func, List<CppExpr> args) {
    method mk (line 41) | public static CppFuncCall mk(String func, CppExpr... args) {
    method print (line 45) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppGoto.java
  class CppGoto (line 25) | public class CppGoto implements CppStmt {
    method CppGoto (line 29) | private CppGoto(String label) {
    method mk (line 33) | public static CppGoto mk(String label) {
    method println (line 37) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppIf.java
  class CppIf (line 29) | public class CppIf implements CppStmt {
    method CppIf (line 34) | private CppIf(List<Pair<CppExpr, CppStmt>> cases, CppStmt elseBranch) {
    method mk (line 42) | public static CppIf mk(CppExpr guard, CppStmt thenBranch) {
    method mk (line 46) | public static CppIf mk(CppExpr guard, CppStmt thenBranch, CppStmt else...
    method mk (line 50) | public static CppIf mk(List<Pair<CppExpr, CppStmt>> cases) {
    method println (line 54) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppLabel.java
  class CppLabel (line 25) | public class CppLabel implements CppStmt {
    method CppLabel (line 29) | public CppLabel(String label) {
    method mk (line 33) | public static CppLabel mk(String label) {
    method println (line 37) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppMethodCall.java
  class CppMethodCall (line 27) | public class CppMethodCall implements CppExpr {
    method CppMethodCall (line 34) | private CppMethodCall(CppExpr rec, String func, List<CppExpr> args, bo...
    method mk (line 41) | public static CppMethodCall mk(CppExpr rec, String func, List<CppExpr>...
    method mk (line 45) | public static CppMethodCall mk(CppExpr rec, String func, CppExpr... ar...
    method mkThruPtr (line 49) | public static CppMethodCall mkThruPtr(CppExpr rec, String func, List<C...
    method mkThruPtr (line 53) | public static CppMethodCall mkThruPtr(CppExpr rec, String func, CppExp...
    method print (line 57) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppNewArray.java
  class CppNewArray (line 24) | public class CppNewArray implements CppExpr {
    method CppNewArray (line 29) | private CppNewArray(String type, CppExpr size) {
    method mk (line 34) | public static CppNewArray mk(String type, CppExpr size) {
    method print (line 38) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppNullptr.java
  type CppNullptr (line 24) | public enum CppNullptr implements CppExpr {
    method print (line 27) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppReturn.java
  class CppReturn (line 25) | public class CppReturn implements CppStmt {
    method CppReturn (line 29) | private CppReturn(CppExpr val) {
    method mk (line 33) | public static CppReturn mk(CppExpr val) {
    method mk (line 37) | public static CppReturn mk() {
    method println (line 41) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppSeq.java
  class CppSeq (line 28) | public class CppSeq implements CppStmt {
    method CppSeq (line 32) | private CppSeq(List<CppStmt> stmts) {
    method mk (line 36) | public static CppSeq mk(List<CppStmt> stmts) {
    method mk (line 43) | public static CppSeq mk(CppStmt... stmts) {
    method skip (line 47) | public static CppSeq skip() {
    method println (line 53) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppStmt.java
  type CppStmt (line 24) | public interface CppStmt {
    method println (line 26) | void println(PrintWriter out, int indent);

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppSubscript.java
  class CppSubscript (line 24) | public class CppSubscript implements CppExpr {
    method CppSubscript (line 29) | private CppSubscript(CppExpr val, CppExpr idx) {
    method mk (line 34) | public static CppSubscript mk(CppExpr val, CppExpr idx) {
    method print (line 38) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppUnop.java
  class CppUnop (line 24) | public class CppUnop implements CppExpr {
    method CppUnop (line 29) | private CppUnop(String op, CppExpr expr) {
    method mk (line 34) | private static CppUnop mk(String op, CppExpr expr) {
    method mkNot (line 38) | public static CppUnop mkNot(CppExpr expr) {
    method mkPreIncr (line 42) | public static CppUnop mkPreIncr(CppExpr expr) {
    method mkDeref (line 46) | public static CppUnop mkDeref(CppExpr expr) {
    method print (line 50) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppVar.java
  class CppVar (line 24) | public class CppVar implements CppExpr {
    method CppVar (line 28) | private CppVar(String var) {
    method mk (line 32) | public static CppVar mk(String var) {
    method toString (line 36) | @Override
    method print (line 41) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppVectorLiteral.java
  class CppVectorLiteral (line 25) | public class CppVectorLiteral implements CppExpr {
    method CppVectorLiteral (line 29) | private CppVectorLiteral(List<CppExpr> elts) {
    method mk (line 33) | public static CppVectorLiteral mk(List<CppExpr> elts) {
    method print (line 37) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppWhile.java
  class CppWhile (line 25) | public class CppWhile implements CppStmt {
    method CppWhile (line 30) | private CppWhile(CppExpr guard, CppStmt body) {
    method mk (line 35) | public static CppWhile mk(CppExpr guard, CppStmt body) {
    method println (line 39) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SAtom.java
  class SAtom (line 25) | public class SAtom implements SLit {
    method SAtom (line 31) | public SAtom(String symbol, List<STerm> args, boolean isNegated) {
    method getSymbol (line 37) | public String getSymbol() {
    method toString (line 41) | @Override
    method varSet (line 59) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SDestructorBody.java
  class SDestructorBody (line 27) | public class SDestructorBody implements SFunctorBody {
    method SDestructorBody (line 33) | public SDestructorBody(List<Var> args_, Term scrutinee_, ConstructorSy...
    method getArgs (line 39) | @Override
    method getRetType (line 44) | @Override
    method isStateful (line 49) | @Override
    method getScrutinee (line 54) | public Term getScrutinee() {
    method getSymbol (line 58) | public ConstructorSymbol getSymbol() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SExprBody.java
  class SExprBody (line 26) | public class SExprBody implements SFunctorBody {
    method SExprBody (line 31) | public SExprBody(List<Var> args_, Term body_) {
    method getBody (line 36) | public Term getBody() {
    method getArgs (line 40) | @Override
    method getRetType (line 45) | @Override
    method isStateful (line 50) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SFunctorBody.java
  type SFunctorBody (line 25) | public interface SFunctorBody {
    method getArity (line 27) | default int getArity() {
    method getArgs (line 31) | List<Var> getArgs();
    method getRetType (line 33) | SType getRetType();
    method isStateful (line 35) | boolean isStateful();

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SFunctorCall.java
  class SFunctorCall (line 26) | public class SFunctorCall implements STerm {
    method SFunctorCall (line 31) | public SFunctorCall(String func, List<STerm> args) {
    method SFunctorCall (line 36) | public SFunctorCall(String func, STerm... args) {
    method toString (line 40) | @Override
    method varSet (line 56) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SInfixBinaryOpAtom.java
  class SInfixBinaryOpAtom (line 24) | public class SInfixBinaryOpAtom implements SLit {
    method SInfixBinaryOpAtom (line 30) | public SInfixBinaryOpAtom(STerm lhs_, String op_, STerm rhs_) {
    method toString (line 36) | @Override
    method varSet (line 41) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SInt.java
  class SInt (line 24) | public class SInt implements STerm {
    method SInt (line 28) | public SInt(int val_) {
    method toString (line 32) | @Override
    method varSet (line 37) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SIntList.java
  class SIntList (line 25) | public class SIntList implements STerm {
    method SIntList (line 29) | public SIntList(List<STerm> ts_) {
    method toString (line 33) | @Override
    method varSet (line 47) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SIntListType.java
  class SIntListType (line 24) | public class SIntListType implements SType {
    method SIntListType (line 28) | public SIntListType(int arity) {
    method getName (line 32) | public String getName() {
    method getDef (line 36) | public String getDef() {
    method equals (line 51) | @Override
    method hashCode (line 59) | @Override
    method toString (line 64) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SIntType.java
  type SIntType (line 22) | public enum SIntType implements SType {
    method toString (line 25) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SLit.java
  type SLit (line 25) | public interface SLit {
    method varSet (line 27) | default Set<SVar> varSet() {
    method varSet (line 33) | void varSet(Set<SVar> vars);

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SRule.java
  class SRule (line 27) | public class SRule {
    method SRule (line 33) | public SRule(SLit head, List<SLit> body) {
    method SRule (line 38) | public SRule(SLit head, SLit... body) {
    method getBody (line 42) | public List<SLit> getBody() {
    method setQueryPlan (line 46) | public void setQueryPlan(List<Pair<Integer, int[]>> queryPlan) {
    method toString (line 50) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SRuleMode.java
  type SRuleMode (line 22) | public enum SRuleMode {

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/STerm.java
  type STerm (line 25) | public interface STerm {
    method varSet (line 27) | default Set<SVar> varSet() {
    method varSet (line 33) | void varSet(Set<SVar> vars);

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SType.java
  type SType (line 22) | public interface SType {}

FILE: src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SVar.java
  class SVar (line 25) | public class SVar implements STerm {
    method SVar (line 29) | public SVar(Var var) {
    method toString (line 37) | @Override
    method varSet (line 42) | @Override
    method hashCode (line 47) | @Override
    method equals (line 55) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/db/BindingTypeArrayWrapper.java
  class BindingTypeArrayWrapper (line 25) | public class BindingTypeArrayWrapper {
    method BindingTypeArrayWrapper (line 28) | public BindingTypeArrayWrapper(BindingType[] arr) {
    method getArr (line 32) | public BindingType[] getArr() {
    method hashCode (line 36) | @Override
    method equals (line 44) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/db/ExampleComparator.java
  class ExampleComparator (line 25) | public class ExampleComparator implements Comparator<Term[]> {
    method compare (line 27) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/db/IndexedFactDb.java
  type IndexedFactDb (line 26) | public interface IndexedFactDb {
    method getSymbols (line 28) | Set<RelationSymbol> getSymbols();
    method getAll (line 30) | Iterable<Term[]> getAll(RelationSymbol sym);
    method isEmpty (line 32) | boolean isEmpty(RelationSymbol sym);
    method countDistinct (line 34) | int countDistinct(RelationSymbol sym);
    method numIndices (line 36) | int numIndices(RelationSymbol sym);
    method countDuplicates (line 38) | int countDuplicates(RelationSymbol sym);
    method get (line 40) | Iterable<Term[]> get(RelationSymbol sym, Term[] key, int index);
    method add (line 42) | boolean add(RelationSymbol sym, Term[] args);
    method addAll (line 44) | boolean addAll(RelationSymbol sym, Iterable<Term[]> tups);
    method hasFact (line 46) | boolean hasFact(RelationSymbol sym, Term[] args);
    method clear (line 48) | void clear();

FILE: src/main/java/edu/harvard/seas/pl/formulog/db/IndexedFactDbBuilder.java
  type IndexedFactDbBuilder (line 25) | public interface IndexedFactDbBuilder<T extends IndexedFactDb> {
    method makeIndex (line 27) | int makeIndex(RelationSymbol sym, BindingType[] pat);
    method build (line 29) | T build();

FILE: src/main/java/edu/harvard/seas/pl/formulog/db/MinChainCover.java
  class MinChainCover (line 35) | public class MinChainCover<T> {
    method MinChainCover (line 39) | public MinChainCover(BiFunction<T, T, Boolean> lessThan) {
    method compute (line 43) | public Iterable<Iterable<T>> compute(Set<T> elts) {
    class Worker (line 47) | private class Worker {
      method toString (line 56) | @Override
      method toString (line 65) | @Override
      method Worker (line 71) | @SuppressWarnings("unchecked")
      method go (line 83) | public Iterable<Iterable<T>> go() {
      method mkBipartiteGraph (line 88) | private void mkBipartiteGraph() {
      method considerEdge (line 107) | private void considerEdge(int i, Node iv, int j) {
      method memoize (line 117) | private void memoize(int i, int j) {
      method computeMaxFlowMap (line 135) | private Map<Edge, Double> computeMaxFlowMap() {
      method mkChains (line 140) | @SuppressWarnings("unchecked")
    type Node (line 172) | private static interface Node {}
    class InnerNode (line 174) | private class InnerNode implements Node {
      method InnerNode (line 179) | public InnerNode(T elt, boolean side) {
      method hashCode (line 184) | @Override
      method equals (line 193) | @Override
      method toString (line 207) | @Override
    class Edge (line 213) | private static class Edge {
      method Edge (line 218) | public Edge(Node src, Node dst) {
      method hashCode (line 223) | @Override
      method equals (line 232) | @Override
      method toString (line 247) | @Override
    method main (line 253) | public static void main(String[] args) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/db/MinIndex.java
  class MinIndex (line 31) | public final class MinIndex {
    method MinIndex (line 33) | private MinIndex() {
    method compute (line 37) | public static <T> Map<Set<T>, Iterable<T>> compute(Set<T> domain, Set<...
    method padIndex (line 52) | private static <T> void padIndex(List<T> idx, Set<T> domain) {
    method computeIndex (line 61) | private static <T> List<T> computeIndex(Iterable<Set<T>> chain) {
    method main (line 75) | public static void main(String[] args) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/db/SortedIndexedFactDb.java
  class SortedIndexedFactDb (line 47) | public class SortedIndexedFactDb implements IndexedFactDb {
    method SortedIndexedFactDb (line 55) | private SortedIndexedFactDb(
    class HashedTuple (line 65) | private static class HashedTuple {
      method hashCode (line 68) | @Override
      method equals (line 73) | @Override
    method getSymbols (line 82) | @Override
    method getAll (line 87) | @Override
    method isEmpty (line 92) | @Override
    method countDistinct (line 97) | @Override
    method countDuplicates (line 102) | @Override
    method getUniqueIndices (line 111) | private Set<IndexedFactSet> getUniqueIndices(RelationSymbol sym) {
    method get (line 119) | @Override
    method hashFilterAdd (line 125) | private boolean hashFilterAdd(RelationSymbol sym, Term[] tup) {
    method hashFilterContains (line 136) | private boolean hashFilterContains(RelationSymbol sym, Term[] tup) {
    method add (line 144) | @Override
    method addAll (line 163) | @Override
    method allNormal (line 187) | private boolean allNormal(Term[] args) {
    method hasFact (line 196) | @Override
    method clear (line 205) | @Override
    method toString (line 217) | @Override
    method toSimplifiedString (line 231) | public String toSimplifiedString() {
    method numIndices (line 246) | @Override
    method getIndexInfo (line 254) | public IndexInfo getIndexInfo(RelationSymbol sym, int idx) {
    method getMasterIndex (line 263) | public int getMasterIndex(RelationSymbol sym) {
    class SortedIndexedFactDbBuilder (line 278) | public static class SortedIndexedFactDbBuilder
      method SortedIndexedFactDbBuilder (line 287) | public SortedIndexedFactDbBuilder(Set<RelationSymbol> allSyms) {
      method makeIndex (line 296) | @Override
      method build (line 311) | @Override
      method mkIndices (line 328) | @SuppressWarnings("unchecked")
      method indicesWellFormed (line 360) | private static boolean indicesWellFormed(
      method countNumNotIgnored (line 369) | private static int countNumNotIgnored(BindingType[] pat) {
      method mkNaiveIndices (line 379) | private List<Pair<IndexedFactSet, BindingType[]>> mkNaiveIndices(
      method mkMinIndices (line 392) | private List<Pair<IndexedFactSet, BindingType[]>> mkMinIndices(
      method mkMinIndices (line 409) | private Map<Integer, Pair<IndexedFactSet, BindingType[]>> mkMinIndices(
      method mkDomain (line 447) | private static Set<Integer> mkDomain(int arity, Set<Integer> ignored) {
      method partitionByIgnoredPositions (line 457) | private static Map<Set<Integer>, Set<Pair<Integer, BindingType[]>>> ...
      method findIgnoredPositions (line 469) | private static Set<Integer> findIgnoredPositions(BindingType[] pat) {
      method compare (line 482) | @Override
    class IndexedFactSet (line 491) | private static class IndexedFactSet {
      method make (line 501) | public static IndexedFactSet make(BindingType[] pat) {
      method make (line 516) | private static IndexedFactSet make(List<Integer> order) {
      method comparatorLength (line 539) | public int comparatorLength() {
      method getAll (line 543) | public Iterable<Term[]> getAll() {
      method clear (line 547) | public void clear() {
      method isEmpty (line 552) | public boolean isEmpty() {
      method IndexedFactSet (line 556) | private IndexedFactSet(NavigableSet<Term[]> s, List<Integer> compara...
      method getId (line 562) | public int getId() {
      method add (line 566) | public boolean add(Term[] arr) {
      method addAll (line 574) | public boolean addAll(Iterable<Term[]> tups) {
      method count (line 589) | public int count() {
      method lookup (line 593) | public Iterable<Term[]> lookup(Term[] tup, BindingType[] pat) {
      method contains (line 608) | public boolean contains(Term[] tup) {
      method toString (line 612) | @Override
    class TermArrayComparator (line 624) | private static class TermArrayComparator implements Comparator<Term[]> {
      method TermArrayComparator (line 628) | public TermArrayComparator(int[] pat) {
      method compare (line 632) | @Override
    class IndexInfo (line 648) | public class IndexInfo {
      method IndexInfo (line 654) | private IndexInfo(int indexId, List<Integer> comparatorOrder, Bindin...
      method getComparatorOrder (line 660) | public List<Integer> getComparatorOrder() {
      method getPattern (line 664) | public BindingType[] getPattern() {
      method getIndexId (line 668) | public int getIndexId() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/db/TupleComparatorGenerator.java
  class TupleComparatorGenerator (line 46) | public class TupleComparatorGenerator extends ClassLoader {
    method generate (line 55) | public Comparator<Term[]> generate(int[] accessPat)
    method generate1 (line 74) | @SuppressWarnings("unchecked")
    method addCompareMethod (line 99) | private void addCompareMethod(ClassGen cg, int[] accessPat) {
    method genCast (line 134) | private InstructionList genCast(InstructionFactory f, int argn) {
    method genComparison (line 143) | private Pair<InstructionList, BranchInstruction> genComparison(Instruc...
    method genLoad (line 155) | private InstructionList genLoad(InstructionFactory f, int argn, int id...
    method genICmp (line 172) | private Pair<InstructionList, BranchInstruction> genICmp(InstructionFa...

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/AbstractStratumEvaluator.java
  class AbstractStratumEvaluator (line 52) | public abstract class AbstractStratumEvaluator implements StratumEvaluat...
    method AbstractStratumEvaluator (line 60) | public AbstractStratumEvaluator(Iterable<IndexedRule> rules, CountingF...
    method processRules (line 65) | private void processRules(Iterable<IndexedRule> rules) {
    method findSplitPositions (line 80) | private static boolean[] findSplitPositions(IndexedRule rule, SmtCallF...
    method findCheckPosition (line 96) | private static int findCheckPosition(IndexedRule rule) {
    method reportFact (line 109) | protected abstract void reportFact(RelationSymbol sym, Term[] args);
    method checkFact (line 111) | protected abstract boolean checkFact(
    method lookup (line 114) | protected abstract Iterable<Iterable<Term[]>> lookup(
    class RuleSuffixEvaluator (line 119) | @SuppressWarnings("serial")
      method RuleSuffixEvaluator (line 130) | protected RuleSuffixEvaluator(
      method RuleSuffixEvaluator (line 151) | protected RuleSuffixEvaluator(
      method doTask (line 174) | @Override
      method evaluate (line 199) | private void evaluate(Term[] ans) throws UncheckedEvaluationException {
      method updateBinding (line 292) | private void updateBinding(SimplePredicate p, Term[] ans) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/EagerStratumEvaluator.java
  class EagerStratumEvaluator (line 53) | public final class EagerStratumEvaluator extends AbstractStratumEvaluator {
    method EagerStratumEvaluator (line 61) | public EagerStratumEvaluator(
    method evaluate (line 71) | @Override
    method reportFact (line 82) | @Override
    method checkFact (line 103) | @Override
    method lookup (line 112) | @Override
    class RulePrefixEvaluator (line 141) | @SuppressWarnings("serial")
      method RulePrefixEvaluator (line 147) | protected RulePrefixEvaluator(IndexedRule rule, Term[] deltaArgs) {
      method handleDelta (line 156) | private final boolean handleDelta(SimplePredicate pred, Substitution s)
      method doTask (line 182) | @Override
      method evaluate (line 200) | private void evaluate() throws EvaluationException {

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/EvalUtil.java
  class EvalUtil (line 31) | public final class EvalUtil {
    method EvalUtil (line 33) | private EvalUtil() {
    method findDelta (line 37) | public static RelationSymbol findDelta(IndexedRule rule) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/Evaluation.java
  type Evaluation (line 26) | public interface Evaluation {
    method run (line 28) | void run() throws EvaluationException;
    method getResult (line 30) | EvaluationResult getResult();
    method hasQuery (line 32) | boolean hasQuery();
    method getQuery (line 34) | UserPredicate getQuery();
    method getInputProgram (line 36) | Program<UserPredicate, BasicRule> getInputProgram();

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/EvaluationException.java
  class EvaluationException (line 22) | public class EvaluationException extends Exception {
    method EvaluationException (line 26) | public EvaluationException() {}
    method EvaluationException (line 28) | public EvaluationException(String message) {
    method EvaluationException (line 32) | public EvaluationException(Throwable cause) {
    method EvaluationException (line 36) | public EvaluationException(String message, Throwable cause) {
    method EvaluationException (line 40) | public EvaluationException(

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/EvaluationResult.java
  type EvaluationResult (line 26) | public interface EvaluationResult {
    method getAll (line 28) | Iterable<UserPredicate> getAll(RelationSymbol sym);
    method getQueryAnswer (line 30) | Iterable<UserPredicate> getQueryAnswer();
    method getSymbols (line 32) | Set<RelationSymbol> getSymbols();
    method getCount (line 34) | int getCount(RelationSymbol sym);

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/IndexedRule.java
  class IndexedRule (line 35) | public class IndexedRule implements Rule<SimplePredicate, SimpleLiteral> {
    method IndexedRule (line 41) | private IndexedRule(
    method make (line 48) | public static IndexedRule make(
    method createIndexes (line 53) | private List<Integer> createIndexes(Function<SimplePredicate, Integer>...
    method getHead (line 85) | @Override
    method getBodySize (line 90) | @Override
    method getBody (line 95) | @Override
    method getDbIndex (line 100) | public Integer getDbIndex(int idx) {
    method toString (line 104) | @Override
    method iterator (line 130) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/PredicateFunctionSetter.java
  class PredicateFunctionSetter (line 59) | public class PredicateFunctionSetter {
    method PredicateFunctionSetter (line 66) | public PredicateFunctionSetter(FunctionDefManager funcs, IndexedFactDb...
    method setDb (line 77) | public void setDb(IndexedFactDb db) {
    method preprocess (line 82) | public void preprocess(Rule<UserPredicate, ComplexLiteral> r) {
    method preprocess (line 89) | public void preprocess(ComplexLiteral l) {
    method preprocess (line 95) | public void preprocess(Term t) {
    method visit (line 102) | @Override
    method visit (line 107) | @Override
    method visit (line 115) | @Override
    method visit (line 120) | @Override
    method visit (line 130) | @Override
    method visit (line 140) | @Override
    method visit (line 159) | @Override
    method visit (line 164) | @Override
    method setPredicateFunction (line 171) | private void setPredicateFunction(DummyFunctionDef def) {
    method turnIgnoredToFree (line 191) | private static BindingType[] turnIgnoredToFree(BindingType[] bindings) {
    method makePredicate (line 202) | private FunctionDef makePredicate(PredicateFunctionSymbol funcSym, Ter...
    method makeAggregate (line 230) | private FunctionDef makeAggregate(
    method padArgs (line 283) | private Term[] padArgs(PredicateFunctionSymbol funcSym) {
    method fillInPaddedArgs (line 292) | private Term[] fillInPaddedArgs(

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/RoundBasedStratumEvaluator.java
  class RoundBasedStratumEvaluator (line 54) | public final class RoundBasedStratumEvaluator extends AbstractStratumEva...
    method RoundBasedStratumEvaluator (line 66) | public RoundBasedStratumEvaluator(
    method evaluate (line 82) | @Override
    method reportFact (line 118) | @Override
    method checkFact (line 134) | @Override
    method updateDbs (line 143) | private void updateDbs() {
    class UpdateDbTask (line 160) | @SuppressWarnings("serial")
      method UpdateDbTask (line 166) | protected UpdateDbTask(RelationSymbol sym, Iterator<Iterable<Term[]>...
      method doTask (line 172) | @Override
    method lookup (line 182) | @Override
    class RulePrefixEvaluator (line 215) | @SuppressWarnings("serial")
      method RulePrefixEvaluator (line 220) | protected RulePrefixEvaluator(IndexedRule rule) {
      method doTask (line 228) | @Override
      method evaluate (line 246) | private void evaluate() throws EvaluationException {
    method recordRoundStart (line 303) | private StopWatch recordRoundStart(int round) {
    method recordRoundEnd (line 316) | private void recordRoundEnd(int round, StopWatch watch) {
    method recordDbUpdateStart (line 325) | private StopWatch recordDbUpdateStart() {
    method recordDbUpdateEnd (line 337) | private void recordDbUpdateEnd(StopWatch watch) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/SemiNaiveEvaluation.java
  class SemiNaiveEvaluation (line 79) | public class SemiNaiveEvaluation implements Evaluation {
    method setup (line 95) | @SuppressWarnings("serial")
    method tweakDeltaAtom (line 206) | private static Rule<UserPredicate, ComplexLiteral> tweakDeltaAtom(
    method checkRule (line 246) | private static void checkRule(ValidRule r, boolean eagerEval) throws I...
    method maybeDoubleCheckSolver (line 262) | private static SmtLibSolver maybeDoubleCheckSolver(SmtLibSolver inner) {
    method makeNaiveSolver (line 269) | private static SmtLibSolver makeNaiveSolver() {
    method getSmtManager (line 273) | private static SmtLibSolver getSmtManager() {
    method getTrackedRelations (line 329) | static Set<RelationSymbol> getTrackedRelations(SymbolManager sm) {
    method chooseScoringFunction (line 347) | static BiFunction<ComplexLiteral, Set<Var>, Integer> chooseScoringFunc...
    method score0 (line 370) | static int score0(ComplexLiteral l, Set<Var> boundVars) {
    method score1 (line 374) | static int score1(ComplexLiteral l, Set<Var> boundVars) {
    method score2 (line 409) | static int score2(ComplexLiteral l, Set<Var> boundVars) {
    method score3 (line 437) | static int score3(ComplexLiteral l, Set<Var> boundVars) {
    method score4 (line 471) | static int score4(ComplexLiteral l, Set<Var> boundVars) {
    method score5 (line 491) | static int score5(ComplexLiteral l, Set<Var> boundVars) {
    method SemiNaiveEvaluation (line 511) | SemiNaiveEvaluation(
    method getInputProgram (line 533) | @Override
    method run (line 538) | @Override
    method evaluateStratum (line 596) | private void evaluateStratum(Stratum stratum) throws EvaluationExcepti...
    method getResult (line 610) | @Override
    class FactIterator (line 643) | static class FactIterator implements Iterator<UserPredicate> {
      method FactIterator (line 648) | public FactIterator(RelationSymbol sym, Iterator<Term[]> bindings) {
      method hasNext (line 653) | @Override
      method next (line 658) | @Override
    method hasQuery (line 664) | @Override
    method getQuery (line 669) | @Override
    method getDb (line 674) | public SortedIndexedFactDb getDb() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/SemiNaiveRule.java
  class SemiNaiveRule (line 37) | public class SemiNaiveRule extends AbstractRule<UserPredicate, ComplexLi...
    method SemiNaiveRule (line 39) | private SemiNaiveRule(UserPredicate head, List<ComplexLiteral> body) {
    method make (line 43) | public static Set<SemiNaiveRule> make(
    method make (line 73) | private static SemiNaiveRule make(
    class DeltaSymbol (line 89) | public static class DeltaSymbol extends AbstractWrappedRelationSymbol<...
      method DeltaSymbol (line 91) | public DeltaSymbol(RelationSymbol baseSymbol) {
      method toString (line 96) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/SmtCallFinder.java
  class SmtCallFinder (line 42) | public class SmtCallFinder {
    method SmtCallFinder (line 47) | public SmtCallFinder() {
    method containsSmtCall (line 55) | public boolean containsSmtCall(Literal l) {
    method visit (line 67) | @Override
    method visit (line 72) | @Override
    method visit (line 82) | @Override
    method visit (line 87) | @Override
    method visit (line 96) | @Override
    method visit (line 109) | @Override
    method visit (line 130) | @Override
    method visit (line 135) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/StratumEvaluator.java
  type StratumEvaluator (line 22) | public interface StratumEvaluator {
    method evaluate (line 24) | void evaluate() throws EvaluationException;

FILE: src/main/java/edu/harvard/seas/pl/formulog/eval/UncheckedEvaluationException.java
  class UncheckedEvaluationException (line 22) | public class UncheckedEvaluationException extends RuntimeException {
    method UncheckedEvaluationException (line 26) | public UncheckedEvaluationException() {}
    method UncheckedEvaluationException (line 28) | public UncheckedEvaluationException(String message) {
    method UncheckedEvaluationException (line 32) | public UncheckedEvaluationException(Throwable cause) {
    method UncheckedEvaluationException (line 36) | public UncheckedEvaluationException(String message, Throwable cause) {
    method UncheckedEvaluationException (line 40) | public UncheckedEvaluationException(

FILE: src/main/java/edu/harvard/seas/pl/formulog/functions/BuiltInFunctionDefFactory.java
  class BuiltInFunctionDefFactory (line 43) | public final class BuiltInFunctionDefFactory {
    method BuiltInFunctionDefFactory (line 47) | public BuiltInFunctionDefFactory(SmtLibSolver smt) {
    method get (line 51) | public FunctionDef get(BuiltInFunctionSymbol sym) {
    type I32Add (line 271) | private enum I32Add implements FunctionDef {
      method getSymbol (line 274) | @Override
      method evaluate (line 279) | @Override
    type I32Sub (line 287) | private enum I32Sub implements FunctionDef {
      method getSymbol (line 290) | @Override
      method evaluate (line 295) | @Override
    type I32Mul (line 303) | private enum I32Mul implements FunctionDef {
      method getSymbol (line 306) | @Override
      method evaluate (line 311) | @Override
    type I32Sdiv (line 319) | private enum I32Sdiv implements FunctionDef {
      method getSymbol (line 322) | @Override
      method evaluate (line 327) | @Override
    type I32Srem (line 338) | private enum I32Srem implements FunctionDef {
      method getSymbol (line 341) | @Override
      method evaluate (line 346) | @Override
    method getSymbol (line 360) | @Override
    method evaluate (line 365) | @Override
    method getSymbol (line 379) | @Override
    method evaluate (line 384) | @Override
    type I32Gt (line 395) | private enum I32Gt implements FunctionDef {
      method getSymbol (line 398) | @Override
      method evaluate (line 403) | @Override
    type I32Gte (line 411) | private enum I32Gte implements FunctionDef {
      method getSymbol (line 414) | @Override
      method evaluate (line 419) | @Override
    type I32Lt (line 427) | private enum I32Lt implements FunctionDef {
      method getSymbol (line 430) | @Override
      method evaluate (line 435) | @Override
    type I32Lte (line 443) | private enum I32Lte implements FunctionDef {
      method getSymbol (line 446) | @Override
      method evaluate (line 451) | @Override
    type I32And (line 459) | private enum I32And implements FunctionDef {
      method getSymbol (line 462) | @Override
      method evaluate (line 467) | @Override
    type I32Or (line 475) | private enum I32Or implements FunctionDef {
      method getSymbol (line 478) | @Override
      method evaluate (line 483) | @Override
    type I32Xor (line 491) | private enum I32Xor implements FunctionDef {
      method getSymbol (line 494) | @Override
      method evaluate (line 499) | @Override
    type I32Neg (line 507) | private enum I32Neg implements FunctionDef {
      method getSymbol (line 510) | @Override
      method evaluate (line 515) | @Override
    method getSymbol (line 525) | @Override
    method evaluate (line 530) | @Override
    method getSymbol (line 541) | @Override
    method evaluate (line 546) | @Override
    method getSymbol (line 557) | @Override
    method evaluate (line 562) | @Override
    method getSymbol (line 573) | @Override
    method evaluate (line 578) | @Override
    method getSymbol (line 589) | @Override
    method evaluate (line 594) | @Override
    method getSymbol (line 605) | @Override
    method evaluate (line 610) | @Override
    type I64Add (line 618) | private enum I64Add implements FunctionDef {
      method getSymbol (line 621) | @Override
      method evaluate (line 626) | @Override
    type I64Sub (line 634) | private enum I64Sub implements FunctionDef {
      method getSymbol (line 637) | @Override
      method evaluate (line 642) | @Override
    type I64Mul (line 650) | private enum I64Mul implements FunctionDef {
      method getSymbol (line 653) | @Override
      method evaluate (line 658) | @Override
    type I64Sdiv (line 666) | private enum I64Sdiv implements FunctionDef {
      method getSymbol (line 669) | @Override
      method evaluate (line 674) | @Override
    type I64Srem (line 685) | private enum I64Srem implements FunctionDef {
      method getSymbol (line 688) | @Override
      method evaluate (line 693) | @Override
    method getSymbol (line 707) | @Override
    method evaluate (line 712) | @Override
    method getSymbol (line 726) | @Override
    method evaluate (line 731) | @Override
    type I64Gt (line 742) | private enum I64Gt implements FunctionDef {
      method getSymbol (line 745) | @Override
      method evaluate (line 750) | @Override
    type I64Gte (line 758) | private enum I64Gte implements FunctionDef {
      method getSymbol (line 761) | @Override
      method evaluate (line 766) | @Override
    type I64Lt (line 774) | private enum I64Lt implements FunctionDef {
      method getSymbol (line 777) | @Override
      method evaluate (line 782) | @Override
    type I64Lte (line 790) | private enum I64Lte implements FunctionDef {
      method getSymbol (line 793) | @Override
      method evaluate (line 798) | @Override
    type I64And (line 806) | private enum I64And implements FunctionDef {
      method getSymbol (line 809) | @Override
      method evaluate (line 814) | @Override
    type I64Or (line 822) | private enum I64Or implements FunctionDef {
      method getSymbol (line 825) | @Override
      method evaluate (line 830) | @Override
    type I64Xor (line 838) | private enum I64Xor implements FunctionDef {
      method getSymbol (line 841) | @Override
      method evaluate (line 846) | @Override
    type I64Neg (line 854) | private enum I64Neg implements FunctionDef {
      method getSymbol (line 857) | @Override
      method evaluate (line 862) | @Override
    type FP32Add (line 869) | private enum FP32Add implements FunctionDef {
      method getSymbol (line 872) | @Override
      method evaluate (line 877) | @Override
    type FP32Sub (line 885) | private enum FP32Sub implements FunctionDef {
      method getSymbol (line 888) | @Override
      method evaluate (line 893) | @Override
    type FP32Mul (line 901) | private enum FP32Mul implements FunctionDef {
      method getSymbol (line 904) | @Override
      method evaluate (line 909) | @Override
    type FP32Div (line 917) | private enum FP32Div implements FunctionDef {
      method getSymbol (line 920) | @Override
      method evaluate (line 925) | @Override
    type FP32Rem (line 936) | private enum FP32Rem implements FunctionDef {
      method getSymbol (line 939) | @Override
      method evaluate (line 944) | @Override
    type FP32Gt (line 955) | private enum FP32Gt implements FunctionDef {
      method getSymbol (line 958) | @Override
      method evaluate (line 963) | @Override
    type FP32Gte (line 971) | private enum FP32Gte implements FunctionDef {
      method getSymbol (line 974) | @Override
      method evaluate (line 979) | @Override
    type FP32Lt (line 987) | private enum FP32Lt implements FunctionDef {
      method getSymbol (line 990) | @Override
      method evaluate (line 995) | @Override
    type FP32Lte (line 1003) | private enum FP32Lte implements FunctionDef {
      method getSymbol (line 1006) | @Override
      method evaluate (line 1011) | @Override
    type FP32Eq (line 1019) | private enum FP32Eq implements FunctionDef {
      method getSymbol (line 1022) | @Override
      method evaluate (line 1027) | @Override
    type FP32Neg (line 1035) | private enum FP32Neg implements FunctionDef {
      method getSymbol (line 1038) | @Override
      method evaluate (line 1043) | @Override
    type FP64Add (line 1050) | private enum FP64Add implements FunctionDef {
      method getSymbol (line 1053) | @Override
      method evaluate (line 1058) | @Override
    type FP64Sub (line 1066) | private enum FP64Sub implements FunctionDef {
      method getSymbol (line 1069) | @Override
      method evaluate (line 1074) | @Override
    type FP64Mul (line 1082) | private enum FP64Mul implements FunctionDef {
      method getSymbol (line 1085) | @Override
      method evaluate (line 1090) | @Override
    type FP64Div (line 1098) | private enum FP64Div implements FunctionDef {
      method getSymbol (line 1101) | @Override
      method evaluate (line 1106) | @Override
    type FP64Rem (line 1117) | private enum FP64Rem implements FunctionDef {
      method getSymbol (line 1120) | @Override
      method evaluate (line 1125) | @Override
    type FP64Gt (line 1136) | private enum FP64Gt implements FunctionDef {
      method getSymbol (line 1139) | @Override
      method evaluate (line 1144) | @Override
    type FP64Gte (line 1152) | private enum FP64Gte implements FunctionDef {
      method getSymbol (line 1155) | @Override
      method evaluate (line 1160) | @Override
    type FP64Lt (line 1168) | private enum FP64Lt implements FunctionDef {
      method getSymbol (line 1171) | @Override
      method evaluate (line 1176) | @Override
    type FP64Lte (line 1184) | private enum FP64Lte implements FunctionDef {
      method getSymbol (line 1187) | @Override
      method evaluate (line 1192) | @Override
    type FP64Eq (line 1200) | private enum FP64Eq implements FunctionDef {
      method getSymbol (line 1203) | @Override
      method evaluate (line 1208) | @Override
    type FP64Neg (line 1216) | private enum FP64Neg implements FunctionDef {
      method getSymbol (line 1219) | @Override
      method evaluate (line 1224) | @Override
    type Beq (line 1231) | private enum Beq implements FunctionDef {
      method getSymbol (line 1234) | @Override
      method evaluate (line 1239) | @Override
    type Bneq (line 1247) | private enum Bneq implements FunctionDef {
      method getSymbol (line 1250) | @Override
      method evaluate (line 1255) | @Override
    method getSymbol (line 1266) | @Override
    method evaluate (line 1271) | @Override
    type ToString (line 1281) | private enum ToString implements FunctionDef {
      method getSymbol (line 1284) | @Override
      method evaluate (line 1289) | @Override
    type StringCmp (line 1299) | private enum StringCmp implements FunctionDef {
      method getSymbol (line 1302) | @Override
      method evaluate (line 1307) | @Override
    type I32Scmp (line 1315) | private enum I32Scmp implements FunctionDef {
      method getSymbol (line 1318) | @Override
      method evaluate (line 1323) | @Override
    type I32Ucmp (line 1331) | private enum I32Ucmp implements FunctionDef {
      method getSymbol (line 1334) | @Override
      method evaluate (line 1339) | @Override
    type I64Scmp (line 1347) | private enum I64Scmp implements FunctionDef {
      method getSymbol (line 1350) | @Override
      method evaluate (line 1355) | @Override
    type I64Ucmp (line 1363) | private enum I64Ucmp implements FunctionDef {
      method getSymbol (line 1366) | @Override
      method evaluate (line 1371) | @Override
    type StringConcat (line 1379) | private enum StringConcat implements FunctionDef {
      method getSymbol (line 1382) | @Override
      method evaluate (line 1387) | @Override
    method getSymbol (line 1398) | @Override
    method evaluate (line 1403) | @Override
    method getSymbol (line 1414) | @Override
    method evaluate (line 1419) | @Override
    method getSymbol (line 1430) | @Override
    method evaluate (line 1435) | @Override
    method getSymbol (line 1449) | @Override
    method evaluate (line 1454) | @Override
    method getSymbol (line 1470) | @Override
    method evaluate (line 1475) | @Override
    method getSymbol (line 1489) | @Override
    method evaluate (line 1494) | @Override
    method getSymbol (line 1509) | @Override
    method evaluate (line 1514) | @Override
    method querySmt (line 1524) | private Pair<SmtStatus, Model> querySmt(SmtLibTerm assertions, boolean...
    method querySmt (line 1529) | private Pair<SmtStatus, Model> querySmt(SmtLibTerm assertions, boolean...
    method breakIntoConjuncts (line 1534) | private List<SmtLibTerm> breakIntoConjuncts(SmtLibTerm assertion) {
    method breakIntoConjunctsNegated (line 1540) | private void breakIntoConjunctsNegated(SmtLibTerm assertion, List<SmtL...
    method breakIntoConjuncts (line 1570) | private void breakIntoConjuncts(SmtLibTerm assertion, List<SmtLibTerm>...
    method negate (line 1589) | private SmtLibTerm negate(Term t) {
    method querySmt (line 1593) | private Pair<SmtStatus, Model> querySmt(
    method querySmtWithMemo (line 1621) | private SmtResult querySmtWithMemo(Set<SmtLibTerm> assertions, boolean...
    method getSymbol (line 1648) | @Override
    method evaluate (line 1653) | @Override
    method getSymbol (line 1672) | @Override
    method evaluate (line 1677) | @Override
    method getSymbol (line 1700) | @Override
    method evaluate (line 1705) | @Override
    method getSymbol (line 1727) | @Override
    method evaluate (line 1732) | @Override
    method extractOptionalTimeout (line 1748) | private static int extractOptionalTimeout(Constructor opt) {
    method getSymbol (line 1758) | @Override
    method evaluate (line 1763) | @Override
    type QueryModel (line 1775) | private enum QueryModel implements FunctionDef {
      method getSymbol (line 1778) | @Override
      method evaluate (line 1783) | @Override
    method boolToBoolTerm (line 1795) | private static Term boolToBoolTerm(boolean b) {
    type Print (line 1803) | private enum Print implements FunctionDef {
      method getSymbol (line 1806) | @Override
      method evaluate (line 1811) | @Override
    method makeCmp (line 1818) | private static <T> Term makeCmp(T x, T y, BiFunction<T, T, Integer> cm...

FILE: src/main/java/edu/harvard/seas/pl/formulog/functions/DummyFunctionDef.java
  class DummyFunctionDef (line 26) | public class DummyFunctionDef implements FunctionDef {
    method DummyFunctionDef (line 31) | public DummyFunctionDef(FunctionSymbol sym) {
    method getSymbol (line 35) | @Override
    method evaluate (line 40) | @Override
    method setDef (line 48) | public void setDef(FunctionDef def) {
    method getDef (line 52) | public Object getDef() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/functions/FunctionDef.java
  type FunctionDef (line 26) | public interface FunctionDef {
    method getSymbol (line 28) | FunctionSymbol getSymbol();
    method evaluate (line 30) | Term evaluate(Term[] args) throws EvaluationException;

FILE: src/main/java/edu/harvard/seas/pl/formulog/functions/FunctionDefManager.java
  class FunctionDefManager (line 31) | public class FunctionDefManager {
    method FunctionDefManager (line 35) | public FunctionDefManager() {
    method register (line 41) | public void register(FunctionDef def) {
    method reregister (line 48) | public void reregister(FunctionDef def) {
    method lookup (line 55) | public FunctionDef lookup(FunctionSymbol symbol) {
    method hasDefinition (line 63) | public boolean hasDefinition(FunctionSymbol sym) {
    method getFunctionSymbols (line 67) | public Set<FunctionSymbol> getFunctionSymbols() {
    method loadBuiltInFunctions (line 71) | public void loadBuiltInFunctions(SmtLibSolver smt) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/functions/OpaqueSetOps.java
  class OpaqueSetOps (line 33) | public final class OpaqueSetOps {
    method OpaqueSetOps (line 35) | private OpaqueSetOps() {
    method getSymbol (line 42) | @Override
    method evaluate (line 47) | @Override
    method getSymbol (line 56) | @Override
    method evaluate (line 61) | @Override
    method getSymbol (line 71) | @Override
    method evaluate (line 76) | @Override
    method getSymbol (line 86) | @Override
    method evaluate (line 91) | @Override
    method getSymbol (line 101) | @Override
    method evaluate (line 106) | @Override
    method getSymbol (line 117) | @Override
    method evaluate (line 122) | @Override
    method getSymbol (line 133) | @Override
    method evaluate (line 138) | @Override
    method getSymbol (line 152) | @Override
    method evaluate (line 157) | @Override
    method getSymbol (line 167) | @Override
    method evaluate (line 172) | @Override
    method getSymbol (line 181) | @Override
    method evaluate (line 186) | @Override
    method getSymbol (line 197) | @Override
    method evaluate (line 202) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/functions/PredicateFunctionDef.java
  type PredicateFunctionDef (line 24) | public interface PredicateFunctionDef extends FunctionDef {
    method getIndex (line 26) | int getIndex();
    method getBindingsForIndex (line 28) | BindingType[] getBindingsForIndex();

FILE: src/main/java/edu/harvard/seas/pl/formulog/functions/PrimitiveConversions.java
  class PrimitiveConversions (line 35) | public final class PrimitiveConversions {
    method PrimitiveConversions (line 37) | private PrimitiveConversions() {
    method getSymbol (line 44) | @Override
    method evaluate (line 49) | @Override
    method getSymbol (line 59) | @Override
    method evaluate (line 64) | @Override
    method getSymbol (line 74) | @Override
    method evaluate (line 79) | @Override
    method getSymbol (line 89) | @Override
    method evaluate (line 94) | @Override
    method getSymbol (line 104) | @Override
    method evaluate (line 109) | @Override
    method getSymbol (line 119) | @Override
    method evaluate (line 124) | @Override
    method getSymbol (line 134) | @Override
    method evaluate (line 139) | @Override
    method getSymbol (line 149) | @Override
    method evaluate (line 154) | @Override
    method getSymbol (line 164) | @Override
    method evaluate (line 169) | @Override
    method getSymbol (line 179) | @Override
    method evaluate (line 184) | @Override
    method getSymbol (line 194) | @Override
    method evaluate (line 199) | @Override
    method getSymbol (line 209) | @Override
    method evaluate (line 214) | @Override
    method getSymbol (line 226) | @Override
    method evaluate (line 231) | @Override
    method getSymbol (line 252) | @Override
    method evaluate (line 257) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/functions/RecordAccessor.java
  class RecordAccessor (line 27) | public class RecordAccessor implements FunctionDef {
    method RecordAccessor (line 32) | public RecordAccessor(FunctionSymbol sym, int index) {
    method getSymbol (line 37) | @Override
    method getIndex (line 42) | public int getIndex() {
    method evaluate (line 46) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/functions/UserFunctionDef.java
  class UserFunctionDef (line 30) | public class UserFunctionDef implements FunctionDef {
    method UserFunctionDef (line 36) | private UserFunctionDef(FunctionSymbol sym, List<Var> params, Term bod...
    method getParams (line 42) | public List<Var> getParams() {
    method getBody (line 46) | public Term getBody() {
    method setBody (line 50) | public void setBody(Term newBody) {
    method getSymbol (line 54) | @Override
    method evaluate (line 59) | @Override
    method get (line 75) | public static UserFunctionDef get(FunctionSymbol sym, List<Var> params...
    method toString (line 79) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/magic/AdornedSymbol.java
  class AdornedSymbol (line 27) | class AdornedSymbol implements WrappedRelationSymbol<RelationSymbol> {
    method AdornedSymbol (line 32) | public AdornedSymbol(RelationSymbol baseSymbol, boolean[] adornment) {
    method getAdornment (line 40) | public boolean[] getAdornment() {
    method toString (line 44) | @Override
    method isIdbSymbol (line 53) | @Override
    method isBottomUp (line 58) | @Override
    method isTopDown (line 63) | @Override
    method getCompileTimeType (line 68) | @Override
    method getArity (line 73) | @Override
    method getBaseSymbol (line 78) | @Override
    method isDisk (line 83) | @Override
    method hashCode (line 88) | @Override
    method equals (line 97) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/magic/Adornments.java
  class Adornments (line 38) | public final class Adornments {
    method Adornments (line 40) | private Adornments() {
    method adorn (line 44) | public static UserPredicate adorn(UserPredicate a, Set<Var> boundVars,...
    method adornRule (line 59) | public static BasicRule adornRule(

FILE: src/main/java/edu/harvard/seas/pl/formulog/magic/MagicSetTransformer.java
  class MagicSetTransformer (line 73) | public class MagicSetTransformer {
    method MagicSetTransformer (line 80) | public MagicSetTransformer(Program<UserPredicate, BasicRule> prog) {
    method transform (line 84) | public BasicProgram transform(boolean useDemandTransformation, boolean...
    method transformForQuery (line 107) | private BasicProgram transformForQuery(
    method makeSeedRule (line 139) | private BasicRule makeSeedRule(UserPredicate adornedQuery) {
    method makeQueryRule (line 143) | private BasicRule makeQueryRule(UserPredicate query) {
    method makeEdbProgram (line 206) | private BasicProgram makeEdbProgram(UserPredicate query) {
    method transformNoQuery (line 279) | private BasicProgram transformNoQuery(
    method applyDemandTransformation (line 301) | private BasicProgram applyDemandTransformation(BasicProgram prog, bool...
    method stripAdornments (line 310) | private BasicProgram stripAdornments(BasicProgram prog) throws Invalid...
    method stripAdornment (line 329) | private static <C extends ComplexLiteral> C stripAdornment(C atom) {
    method adorn (line 358) | private Set<Pair<BasicRule, Integer>> adorn(Set<RelationSymbol> seeds)
    method makeMagicRules (line 424) | private Set<BasicRule> makeMagicRules(Set<Pair<BasicRule, Integer>> ad...
    method exploreTopDown (line 432) | private boolean exploreTopDown(RelationSymbol sym) {
    method makeMagicRules (line 442) | private Set<BasicRule> makeMagicRules(BasicRule r, int number) {
    method liveVarsByAtom (line 510) | private List<Set<Var>> liveVarsByAtom(BasicRule r) {
    method createSupAtom (line 523) | private UserPredicate createSupAtom(
    method createInputAtom (line 539) | private UserPredicate createInputAtom(UserPredicate a) {
    class SupSymbol (line 554) | public static class SupSymbol implements RelationSymbol {
      method SupSymbol (line 560) | public SupSymbol(int ruleNum, int supCount, int arity) {
      method getArity (line 566) | @Override
      method hashCode (line 571) | @Override
      method equals (line 581) | @Override
      method toString (line 593) | @Override
      method getCompileTimeType (line 598) | @Override
      method isIdbSymbol (line 603) | @Override
      method isDisk (line 608) | @Override
      method isBottomUp (line 613) | @Override
      method isTopDown (line 618) | @Override
    class InputSymbol (line 624) | public static class InputSymbol extends AbstractWrappedRelationSymbol<...
      method InputSymbol (line 628) | public InputSymbol(AdornedSymbol baseSymbol) {
      method getArity (line 637) | @Override
      method toString (line 642) | @Override
      method getCompileTimeType (line 647) | @Override
      method isBottomUp (line 652) | @Override
      method isTopDown (line 657) | @Override
    method isStratified (line 663) | private boolean isStratified(BasicProgram p) {
    method adjustAdornedRules (line 677) | private Set<BasicRule> adjustAdornedRules(Collection<BasicRule> adRule...
    method stratify (line 693) | private ProgramImpl stratify(BasicProgram p, Set<BasicRule> adornedRules)
    method makePositive (line 707) | private <C extends ComplexLiteral> C makePositive(C atom) {
    method makePositive (line 734) | private List<ComplexLiteral> makePositive(Iterable<ComplexLiteral> ato...
    class PositiveSymbol (line 745) | private static class PositiveSymbol extends AbstractWrappedRelationSym...
      method PositiveSymbol (line 747) | public PositiveSymbol(RelationSymbol baseSymbol) {
      method toString (line 751) | @Override
      method getCompileTimeType (line 756) | @Override
      method isBottomUp (line 761) | @Override
      method isTopDown (line 766) | @Override
    class HiddenPredicateFinder (line 772) | private static class HiddenPredicateFinder {
      method HiddenPredicateFinder (line 778) | public HiddenPredicateFinder(Program<UserPredicate, BasicRule> origP...
      method findHiddenPredicates (line 782) | private void findHiddenPredicates(Term t, Set<RelationSymbol> s) {
      method allSeenPredicates (line 786) | public Set<RelationSymbol> allSeenPredicates() {
      method visit (line 790) | public Set<RelationSymbol> visit(UserFunctionDef def) {
      method visit (line 798) | private void visit(ComplexLiteral l, Set<RelationSymbol> s) {
      method visit (line 820) | public Set<RelationSymbol> visit(
      method visit (line 833) | @Override
      method visit (line 838) | @Override
      method visit (line 846) | @Override
      method visit (line 851) | @Override
      method visit (line 861) | @Override
      method visit (line 870) | @Override
      method visit (line 890) | @Override
      method visit (line 895) | @Override
    class ProgramImpl (line 903) | private class ProgramImpl implements BasicProgram {
      method ProgramImpl (line 909) | public ProgramImpl(Set<BasicRule> rs, UserPredicate query) throws In...
      method getFunctionSymbols (line 960) | @Override
      method getFactSymbols (line 965) | @Override
      method getRuleSymbols (line 970) | @Override
      method getDef (line 975) | @Override
      method getFacts (line 980) | @Override
      method getRules (line 986) | @Override
      method getSymbolManager (line 992) | @Override
      method hasQuery (line 997) | @Override
      method getQuery (line 1002) | @Override
      method getFunctionCallFactory (line 1007) | @Override
      method getUninterpretedFunctionSymbols (line 1012) | @Override
      method getTypeSymbols (line 1017) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/FactFileParser.java
  class FactFileParser (line 27) | class FactFileParser {
    method FactFileParser (line 31) | public FactFileParser(ParsingContext parsingContext) {
    method loadFacts (line 35) | public void loadFacts(TsvFileContext ctx, int expectedArity, Set<Term[...

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/Identifier.java
  class Identifier (line 25) | public class Identifier {
    method Identifier (line 29) | private Identifier(Object val) {
    method make (line 33) | public static Identifier make(Var var) {
    method make (line 37) | public static Identifier make(FunctionSymbol sym) {
    method isFunctionSymbol (line 41) | public boolean isFunctionSymbol() {
    method isVar (line 45) | public boolean isVar() {
    method asFunctionSymbol (line 49) | public FunctionSymbol asFunctionSymbol() {
    method asVar (line 53) | public Var asVar() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/ParseException.java
  class ParseException (line 22) | public class ParseException extends Exception {
    method ParseException (line 29) | public ParseException(String fileName, int lineNo, String message) {
    method ParseException (line 36) | public ParseException(int lineNo, String message) {
    method ParseException (line 40) | public ParseException(UncheckedParseException e) {
    method getFileName (line 46) | public String getFileName() {
    method getLineNo (line 50) | public int getLineNo() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/Parser.java
  class Parser (line 54) | public class Parser {
    method getParser (line 58) | private FormulogParser getParser(Reader r, boolean isTsv) throws Parse...
    method parse (line 69) | public BasicProgram parse(Reader r) throws ParseException {
    method parse (line 73) | public BasicProgram parse(Reader r, List<Path> inputDirs) throws Parse...
    method parseFacts (line 86) | public Set<Term[]> parseFacts(RelationSymbol sym, Reader factStream) t...
    method loadExternalEdbs (line 94) | private void loadExternalEdbs(
    method readEdbFromFile (line 135) | private void readEdbFromFile(RelationSymbol sym, Path inputDir, Set<Te...

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/ParsingContext.java
  class ParsingContext (line 34) | class ParsingContext {
    method symbolManager (line 44) | public SymbolManager symbolManager() {
    method functionCallFactory (line 48) | public FunctionCallFactory functionCallFactory() {
    method functionDefManager (line 52) | public FunctionDefManager functionDefManager() {
    method recordLabels (line 56) | public Map<FunctionSymbol, Pair<AlgebraicDataType, Integer>> recordLab...
    method constructorLabels (line 60) | public Map<ConstructorSymbol, FunctionSymbol[]> constructorLabels() {
    method typeManager (line 64) | public TypeManager typeManager() {
    method nestedFunctionCounters (line 68) | public Map<String, AtomicInteger> nestedFunctionCounters() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/ParsingUtil.java
  class ParsingUtil (line 45) | final class ParsingUtil {
    method ParsingUtil (line 47) | private ParsingUtil() {
    method extractParams (line 51) | public static List<Param> extractParams(ParsingContext pc, ParameterLi...
    method extractParam (line 59) | public static Param extractParam(ParsingContext pc, ParameterContext c...
    method extractFunDeclaration (line 81) | public static Pair<FunctionSymbol, List<Var>> extractFunDeclaration(
    method extractFunDeclarations (line 106) | public static List<Pair<FunctionSymbol, List<Var>>> extractFunDeclarat...
    method varsToIds (line 111) | public static Map<String, Identifier> varsToIds(Iterable<Var> vars) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/TermExtractor.java
  class TermExtractor (line 104) | class TermExtractor {
    method TermExtractor (line 109) | public TermExtractor(ParsingContext parsingContext) {
    method extract (line 114) | public synchronized Term extract(TermContext ctx) {
    method extractList (line 125) | public synchronized List<Term> extractList(List<TermContext> ctxs) {
    method extractArray (line 133) | public synchronized Term[] extractArray(List<TermContext> ctxs) {
    method pushIds (line 143) | public synchronized void pushIds(Map<String, Identifier> ids) {
    method popIds (line 147) | public synchronized Map<String, Identifier> popIds() {
    method assertNotInFormula (line 157) | private void assertNotInFormula(int lineNo, String msg) {
    method toggleInFormula (line 163) | private void toggleInFormula() {
    method visitHoleTerm (line 167) | @Override
    method visitVarTerm (line 172) | @Override
    method visitStringTerm (line 184) | @Override
    method visitConsTerm (line 190) | @Override
    method isSpecialFormulaCtor (line 196) | private boolean isSpecialFormulaCtor(String name) {
    method isSpecialFormulaCtor (line 208) | private boolean isSpecialFormulaCtor(ConstructorSymbol sym) {
    method visitIndexedFunctor (line 232) | @Override
    method adjustFunctorArgs (line 283) | private void adjustFunctorArgs(Symbol sym, Term[] args) {
    method parseBool (line 295) | private Term parseBool(IndexedFunctorContext ctx) {
    method makeFunctor (line 310) | private Term makeFunctor(int lineNo, Symbol sym, Term[] args) {
    method visitFoldTerm (line 345) | @Override
    method visitTupleTerm (line 372) | @Override
    method visitI32Term (line 380) | @Override
    method visitI64Term (line 392) | @Override
    method visitFloatTerm (line 407) | @Override
    method visitDoubleTerm (line 412) | @Override
    method visitSpecialFPTerm (line 417) | @Override
    method visitRecordTerm (line 436) | @Override
    method visitRecordUpdateTerm (line 453) | @Override
    method handleRecordEntries (line 473) | private Pair<ConstructorSymbol, Map<Integer, Term>> handleRecordEntries(
    method visitUnopTerm (line 502) | @Override
    method makeBoolMatch (line 541) | private Term makeBoolMatch(Term matchee, Term ifTrue, Term ifFalse) {
    method tokenToBinopSym (line 547) | private FunctionSymbol tokenToBinopSym(int tokenType) {
    method makeNonFunctionBinop (line 580) | private Term makeNonFunctionBinop(int tokenType, Term lhs, Term rhs) {
    method visitBinopTerm (line 591) | @Override
    method visitListTerm (line 609) | @Override
    method visitParensTerm (line 620) | @Override
    method makeExitFormula (line 625) | private Term makeExitFormula(Term t) {
    method makeEnterFormula (line 629) | private Term makeEnterFormula(Term t) {
    method visitFormulaTerm (line 633) | @Override
    method visitNotFormula (line 644) | @Override
    method visitBinopFormula (line 650) | @Override
    method visitLetFormula (line 677) | @Override
    method visitQuantifiedFormula (line 691) | @Override
    method parsePatternList (line 717) | private Term parsePatternList(NonEmptyTermListContext ctx) {
    method parseFormulaVarList (line 729) | private Term parseFormulaVarList(NonEmptyTermListContext ctx) {
    method parseNonEmptyTermList (line 741) | private Term parseNonEmptyTermList(
    method visitIteTerm (line 753) | @Override
    method visitTermSymFormula (line 763) | @Override
    method extractSolverSymbol (line 770) | private Term extractSolverSymbol(Term id, Type type) {
    method visitOutermostCtor (line 777) | public Term visitOutermostCtor(OutermostCtorContext ctx) {
    method visitMatchExpr (line 797) | @Override
    method visitLetExpr (line 816) | @Override
    method visitLetFunExpr (line 842) | @Override
    method visitIfExpr (line 883) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/TopLevelParser.java
  class TopLevelParser (line 88) | class TopLevelParser {
    method TopLevelParser (line 92) | public TopLevelParser(ParsingContext parsingContext) {
    method parse (line 96) | public Pair<BasicProgram, Set<RelationSymbol>> parse(ProgContext ctx) ...
    class TopLevelVisitor (line 103) | private final class TopLevelVisitor extends FormulogBaseVisitor<Void> {
      method visitFunDecl (line 114) | @Override
      method visitRelDecl (line 143) | @Override
      method visitTypeAlias (line 186) | @Override
      method visitTypeDecl (line 201) | @Override
      method handleAdtDef (line 220) | private void handleAdtDef(AdtDefContext ctx, AlgebraicDataType type,...
      method handleRecordDef (line 255) | private void handleRecordDef(
      method parseTypeDefLHS (line 291) | private Pair<TypeSymbol, List<TypeVar>> parseTypeDefLHS(
      method visitUninterpSortDecl (line 304) | @Override
      method visitUninterpFunDecl (line 310) | @Override
      method hasSmtType (line 342) | private boolean hasSmtType(Type type) {
      method visitClauseStmt (line 347) | @Override
      method makeRules (line 363) | private Set<BasicRule> makeRules(int lineNo, ComplexLiteral head) {
      method makeRules (line 367) | private Set<BasicRule> makeRules(
      method visitFactStmt (line 385) | @Override
      method visitQueryStmt (line 408) | @Override
      method termsToLiterals (line 430) | List<ComplexLiteral> termsToLiterals(Iterable<TermContext> ctxs) {
      method termToLiteral (line 438) | private ComplexLiteral termToLiteral(TermContext ctx) {
      method program (line 470) | public BasicProgram program() throws ParseException {

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/TypeExtractor.java
  class TypeExtractor (line 44) | class TypeExtractor {
    method TypeExtractor (line 48) | public TypeExtractor(ParsingContext parsingContext) {
    method extract (line 52) | public Type extract(TypeContext ctx) {
    method extract (line 62) | public List<Type> extract(List<TypeContext> ctxs) {
    method visitTupleType (line 73) | @Override
    method visitTypeVar (line 83) | @Override
    method visitTypeRef (line 88) | @Override
    method visitParenType (line 161) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/UncheckedParseException.java
  class UncheckedParseException (line 22) | public class UncheckedParseException extends RuntimeException {
    method UncheckedParseException (line 28) | public UncheckedParseException(int lineNo, String message) {
    method UncheckedParseException (line 34) | public UncheckedParseException(int lineNo, Throwable cause) {
    method UncheckedParseException (line 40) | public UncheckedParseException(ParseException e) {
    method getLineNo (line 46) | public int getLineNo() {
    method getFileName (line 50) | public String getFileName() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/VariableCheckPass.java
  class VariableCheckPass (line 57) | public class VariableCheckPass {
    method VariableCheckPass (line 61) | public VariableCheckPass(SymbolManager sm) {
    method checkFunction (line 65) | public Term checkFunction(Iterable<Var> arguments, Term body) throws V...
    method checkRule (line 72) | public Set<BasicRule> checkRule(List<UserPredicate> heads, List<Comple...
    method checkFact (line 101) | public Term[] checkFact(Term[] fact) throws VariableCheckPassException {
    class PassContext (line 115) | private class PassContext {
      method PassContext (line 120) | public PassContext(Iterable<Var> seed) {
      method PassContext (line 127) | public PassContext() {}
      method checkRule (line 129) | public Set<BasicRule> checkRule(List<UserPredicate> heads, List<Comp...
      method checkLiteral (line 142) | public ComplexLiteral checkLiteral(ComplexLiteral l) {
      method checkTerm (line 160) | public Term checkTerm(Term t) {
      method checkExpr (line 194) | public Expr checkExpr(Expr e) {
      method updatePlaceholder (line 251) | private Pair<PredicateFunctionSymbol, Term[]> updatePlaceholder(
      method checkCounts (line 279) | public void checkCounts() throws VariableCheckPassException {
    method looksLikeHole (line 296) | private static boolean looksLikeHole(Var x) {
    method looksAnonymous (line 300) | private static boolean looksAnonymous(Var x) {
    method looksLikeTrueAnonymousVar (line 304) | private static boolean looksLikeTrueAnonymousVar(Var x) {
    method looksLikeQuasiAnonymousVar (line 308) | private static boolean looksLikeQuasiAnonymousVar(Var x) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/parsing/VariableCheckPassException.java
  class VariableCheckPassException (line 22) | public class VariableCheckPassException extends Exception {
    method VariableCheckPassException (line 26) | public VariableCheckPassException(String message) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/AbstractSmtLibSolver.java
  class AbstractSmtLibSolver (line 46) | public abstract class AbstractSmtLibSolver implements SmtLibSolver {
    method AbstractSmtLibSolver (line 82) | public AbstractSmtLibSolver() {
    method isIncremental (line 97) | protected abstract boolean isIncremental();
    method start (line 99) | @Override
    method destroy (line 114) | @Override
    method destroyAll (line 129) | public static synchronized void destroyAll() {
    method finalize (line 135) | @Override
    method start (line 141) | protected abstract void start() throws EvaluationException;
    method makeAssertions (line 143) | protected abstract Pair<Collection<SolverVariable>, Collection<SolverV...
    method cleanup (line 146) | protected abstract void cleanup() throws EvaluationException;
    method makeResult (line 148) | private SmtResult makeResult(SmtStatus status, Map<SolverVariable, Ter...
    method check (line 153) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/BestMatchSmtManager.java
  class BestMatchSmtManager (line 33) | public class BestMatchSmtManager implements SmtLibSolver {
    method BestMatchSmtManager (line 39) | public BestMatchSmtManager(int size) {
    method check (line 44) | @Override
    method compare (line 69) | @Override
    method score (line 75) | private double score(Collection<SmtLibTerm> conjuncts, CheckSatAssumin...
    method start (line 92) | @Override
    method destroy (line 101) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/BoolectorProcessFactory.java
  class BoolectorProcessFactory (line 27) | public class BoolectorProcessFactory implements ExternalSolverProcessFac...
    method BoolectorProcessFactory (line 31) | private BoolectorProcessFactory() {
    method get (line 35) | public static BoolectorProcessFactory get() {
    method newProcess (line 46) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/CallAndResetSolver.java
  class CallAndResetSolver (line 30) | public class CallAndResetSolver extends AbstractSmtLibSolver {
    method makeAssertions (line 32) | @Override
    method cleanup (line 45) | @Override
    method start (line 51) | @Override
    method isIncremental (line 57) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/CheckSatAssumingSolver.java
  class CheckSatAssumingSolver (line 46) | public class CheckSatAssumingSolver extends AbstractSmtLibSolver {
    method clearCache (line 51) | private void clearCache() throws EvaluationException {
    method getCache (line 69) | public Set<SmtLibTerm> getCache() {
    method makeAssertions (line 73) | @Override
    method makeImp (line 112) | private SmtLibTerm makeImp(SolverVariable x, SmtLibTerm assertion) {
    method makeIndicatorVar (line 117) | private SolverVariable makeIndicatorVar(SmtLibTerm assertion) {
    method cleanup (line 126) | @Override
    method start (line 133) | @Override
    method isIncremental (line 142) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/Cvc4ProcessFactory.java
  class Cvc4ProcessFactory (line 27) | public class Cvc4ProcessFactory implements ExternalSolverProcessFactory {
    method Cvc4ProcessFactory (line 31) | private Cvc4ProcessFactory() {
    method get (line 35) | public static Cvc4ProcessFactory get() {
    method newProcess (line 46) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/DoubleCheckingSolver.java
  class DoubleCheckingSolver (line 28) | public class DoubleCheckingSolver implements SmtLibSolver {
    method DoubleCheckingSolver (line 33) | public DoubleCheckingSolver(SmtLibSolver inner) {
    method start (line 37) | @Override
    method check (line 43) | @Override
    method destroy (line 57) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/ExternalSolverProcessFactory.java
  type ExternalSolverProcessFactory (line 24) | public interface ExternalSolverProcessFactory {
    method newProcess (line 26) | Process newProcess(boolean incremental) throws IOException;

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/NotThreadSafeQueueSmtManager.java
  class NotThreadSafeQueueSmtManager (line 28) | public class NotThreadSafeQueueSmtManager implements SmtLibSolver {
    method NotThreadSafeQueueSmtManager (line 34) | public NotThreadSafeQueueSmtManager(int size, Supplier<SmtLibSolver> m...
    method check (line 42) | @Override
    method start (line 51) | @Override
    method destroy (line 60) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/PerThreadSmtManager.java
  class PerThreadSmtManager (line 29) | public class PerThreadSmtManager implements SmtLibSolver {
    method PerThreadSmtManager (line 34) | public PerThreadSmtManager(Supplier<SmtLibSolver> managerMaker) {
    method check (line 51) | @Override
    method start (line 61) | @Override
    method destroy (line 66) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/PushPopNaiveSolver.java
  class PushPopNaiveSolver (line 30) | public class PushPopNaiveSolver extends AbstractSmtLibSolver {
    method isIncremental (line 32) | @Override
    method start (line 37) | @Override
    method makeAssertions (line 43) | @Override
    method cleanup (line 57) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/PushPopSolver.java
  class PushPopSolver (line 33) | public class PushPopSolver extends AbstractSmtLibSolver {
    method makeAssertions (line 37) | @Override
    method findDiffPos (line 62) | private int findDiffPos(Collection<SmtLibTerm> assertions) {
    method shrinkCache (line 78) | private void shrinkCache(int tgtSize) throws EvaluationException {
    method growCache (line 87) | private void growCache(Iterator<SmtLibTerm> assertions) throws Evaluat...
    method cleanup (line 96) | @Override
    method start (line 101) | @Override
    method isIncremental (line 107) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/QueueSmtManager.java
  class QueueSmtManager (line 29) | public class QueueSmtManager implements SmtLibSolver {
    method QueueSmtManager (line 34) | public QueueSmtManager(int size, Supplier<SmtLibSolver> maker) {
    method check (line 42) | @Override
    method start (line 56) | @Override
    method destroy (line 65) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/SingleShotSolver.java
  class SingleShotSolver (line 31) | public class SingleShotSolver extends AbstractSmtLibSolver {
    method makeAssertions (line 35) | @Override
    method start (line 50) | @Override
    method cleanup (line 55) | @Override
    method start (line 61) | public synchronized void start(Program<?, ?> prog) throws EvaluationEx...
    method isIncremental (line 66) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/SmtLibParser.java
  class SmtLibParser (line 52) | public class SmtLibParser {
    method SmtLibParser (line 57) | public SmtLibParser(SymbolManager symbolManager, Map<String, SolverVar...
    method getModel (line 62) | public Map<SolverVariable, Term> getModel(Reader r) throws IOException...
    method consumeComment (line 80) | private void consumeComment(Tokenizer t) throws IOException, SmtLibPar...
    method parseFunctionDef (line 89) | private void parseFunctionDef(Map<SolverVariable, Term> m, Tokenizer t)
    type TermType (line 123) | private static enum TermType {
    method stripSymType (line 132) | public static AlgebraicDataType stripSymType(AlgebraicDataType symType) {
    method shouldRecord (line 137) | public static boolean shouldRecord(AlgebraicDataType type) throws SmtL...
    method die (line 148) | private static void die(String msg) throws SmtLibParseException {
    method shouldRecord1 (line 152) | private static boolean shouldRecord1(AlgebraicDataType type, Set<Symbo...
    method getTermType (line 202) | private TermType getTermType(AlgebraicDataType type) throws SmtLibPars...
    method parseIdentifier (line 244) | private String parseIdentifier(Tokenizer t) throws IOException, SmtLib...
    method parseType (line 261) | private void parseType(Tokenizer t) throws IOException, SmtLibParseExc...
    method parseBv (line 268) | private long parseBv(Tokenizer t) throws IOException, SmtLibParseExcep...
    method parseTerm (line 283) | private Term parseTerm(Tokenizer t, AlgebraicDataType type)
    method parseString (line 385) | private Term parseString(Tokenizer t) throws IOException, SmtLibParseE...
    method parseADTTerm (line 404) | private Term parseADTTerm(Tokenizer t, AlgebraicDataType type)
    method skipRestOfSExp (line 444) | private void skipRestOfSExp(Tokenizer t) throws IOException, SmtLibPar...
    class Tokenizer (line 458) | private static class Tokenizer {
      method Tokenizer (line 462) | public Tokenizer(Reader r) {
      method ignoreWhitespace (line 475) | public void ignoreWhitespace(boolean ignore) {
      method peek (line 489) | public String peek() throws IOException, SmtLibParseException {
      method next (line 495) | public String next() throws IOException, SmtLibParseException {
      method hasNext (line 512) | public boolean hasNext() throws IOException {
      method consume (line 518) | public void consume(String s) throws IOException, SmtLibParseExcepti...
    class SmtLibParseException (line 531) | @SuppressWarnings("serial")
      method SmtLibParseException (line 534) | public SmtLibParseException(String message) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/SmtLibShim.java
  class SmtLibShim (line 80) | public class SmtLibShim {
    method SmtLibShim (line 95) | public SmtLibShim(Reader in, Writer out) {
    method SmtLibShim (line 99) | public SmtLibShim(Reader in, Writer out, Writer log) {
    method initialize (line 106) | public void initialize(Program<?, ?> prog, boolean declareAdts) {
    method checkSuccess (line 119) | private void checkSuccess() throws EvaluationException {
    method makeAssertion (line 137) | public void makeAssertion(SmtLibTerm assertion) throws EvaluationExcep...
    method reset (line 166) | public void reset() throws EvaluationException {
    method resetAssertions (line 175) | public void resetAssertions() throws EvaluationException {
    method push (line 180) | public void push() throws EvaluationException {
    method pop (line 188) | public void pop() throws EvaluationException {
    method pop (line 192) | public void pop(int n) throws EvaluationException {
    method checkSat (line 203) | public SmtStatus checkSat(int timeout) throws EvaluationException {
    method setTimeout (line 207) | private void setTimeout(int timeout) throws EvaluationException {
    method checkSatAssuming (line 218) | public SmtStatus checkSatAssuming(
    method getModel (line 271) | public Map<SolverVariable, Term> getModel() throws EvaluationException {
    method parseModel (line 283) | public Map<SolverVariable, Term> parseModel()
    method flush (line 289) | public void flush() {
    method setLogic (line 296) | public void setLogic(String logic) throws EvaluationException {
    method print (line 301) | public void print(String s) {
    method println (line 308) | private void println(String s) {
    method printComment (line 313) | public void printComment(String comment) {
    method print (line 317) | public void print(SolverVariable x) {
    method print (line 325) | public void print(Symbol sym) {
    method print (line 329) | public void print(Type type) {
    method getTypeAnnotation (line 333) | public String getTypeAnnotation(ConstructorSymbol sym) {
    method toSmtSymbol (line 342) | private String toSmtSymbol(SolverVariable x) {
    method declareSymbols (line 346) | private void declareSymbols(SmtLibTerm t) throws EvaluationException {
    method makeDeclarations (line 391) | public void makeDeclarations() {
    class DeclarationGatherer (line 410) | private class DeclarationGatherer {
      method DeclarationGatherer (line 415) | public DeclarationGatherer(boolean declareAdts) {
      method go (line 419) | public void go(Program<?, ?> prog) {
      method pushDeclaration (line 430) | private void pushDeclaration() {
      method declareUninterpretedFunctions (line 436) | private void declareUninterpretedFunctions(Set<ConstructorSymbol> fu...
      method declareSorts (line 451) | private void declareSorts(Set<TypeSymbol> sorts) {
      method declareScc (line 463) | private void declareScc(Set<TypeSymbol> sorts) {
      method declareUninterpretedSort (line 475) | private void declareUninterpretedSort(TypeSymbol sort) {
      method declareAdtSorts (line 481) | private void declareAdtSorts(Set<TypeSymbol> sorts) {
      method declareAdtSort (line 496) | private void declareAdtSort(AlgebraicDataType type) {
      method declareConstructor (line 511) | private void declareConstructor(ConstructorScheme c) {
    method stringifySymbol (line 523) | private String stringifySymbol(Symbol sym) {
    method stringifyType (line 527) | private String stringifyType(Type type) {
    class SortDependencyFinder (line 599) | private class SortDependencyFinder {
      method SortDependencyFinder (line 603) | public SortDependencyFinder(Set<TypeSymbol> types) {
      method push (line 609) | private void push(TypeSymbol sym) {
      method compute (line 615) | private Graph<TypeSymbol, DefaultEdge> compute() {
      method extractTypeSymbols (line 640) | private Set<TypeSymbol> extractTypeSymbols(Type type) {
      method isDeclarableTypeSymbol (line 673) | private boolean isDeclarableTypeSymbol(TypeSymbol sym) {
    class MiniTypeInferer (line 704) | private class MiniTypeInferer {
      method inferTypes (line 709) | public List<Pair<ConstructorSymbol, Type>> inferTypes(Term t) {
      method inferTypes1 (line 721) | private List<Pair<ConstructorSymbol, Type>> inferTypes1(Term t) {
      method unifyConstraints (line 762) | private void unifyConstraints() {
      method handleVar (line 806) | private void handleVar(TypeVar x, Type t) {
    method needsTypeAnnotation (line 820) | public static boolean needsTypeAnnotation(ConstructorSymbol sym) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/SmtLibSolver.java
  type SmtLibSolver (line 27) | public interface SmtLibSolver {
    method start (line 29) | void start(Program<?, ?> prog) throws EvaluationException;
    method check (line 31) | SmtResult check(Collection<SmtLibTerm> t, boolean getModel, int timeout)
    method destroy (line 34) | void destroy();

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/SmtResult.java
  class SmtResult (line 24) | public class SmtResult {
    method SmtResult (line 31) | public SmtResult(SmtStatus status, Model model, int solverId, int task...
    method hashCode (line 38) | @Override
    method equals (line 49) | @Override
    method toString (line 64) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/SmtStatus.java
  type SmtStatus (line 22) | public enum SmtStatus {

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/SmtStrategy.java
  class SmtStrategy (line 22) | public class SmtStrategy {
    type Tag (line 24) | public enum Tag {
    method SmtStrategy (line 50) | public SmtStrategy(Tag tag, Object metadata) {
    method getTag (line 55) | public Tag getTag() {
    method getMetadata (line 59) | public Object getMetadata() {
    method hashCode (line 63) | @Override
    method equals (line 72) | @Override
    method toString (line 85) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/YicesProcessFactory.java
  class YicesProcessFactory (line 27) | public class YicesProcessFactory implements ExternalSolverProcessFactory {
    method YicesProcessFactory (line 31) | private YicesProcessFactory() {
    method get (line 35) | public static YicesProcessFactory get() {
    method newProcess (line 46) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/smt/Z3ProcessFactory.java
  class Z3ProcessFactory (line 25) | public class Z3ProcessFactory implements ExternalSolverProcessFactory {
    method Z3ProcessFactory (line 29) | private Z3ProcessFactory() {
    method get (line 33) | public static Z3ProcessFactory get() {
    method newProcess (line 44) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/AbstractSymbol.java
  class AbstractSymbol (line 22) | abstract class AbstractSymbol implements Symbol {
    method AbstractSymbol (line 27) | public AbstractSymbol(String name, int arity) {
    method getArity (line 32) | @Override
    method toString (line 37) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/AbstractTypedSymbol.java
  class AbstractTypedSymbol (line 24) | abstract class AbstractTypedSymbol extends AbstractSymbol implements Typ...
    method AbstractTypedSymbol (line 28) | public AbstractTypedSymbol(String name, int arity, FunctorType type) {
    method getCompileTimeType (line 33) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/AbstractWrappedRelationSymbol.java
  class AbstractWrappedRelationSymbol (line 24) | public abstract class AbstractWrappedRelationSymbol<R extends RelationSy...
    method AbstractWrappedRelationSymbol (line 29) | public AbstractWrappedRelationSymbol(R baseSymbol) {
    method getBaseSymbol (line 33) | @Override
    method getCompileTimeType (line 38) | @Override
    method getArity (line 43) | @Override
    method isIdbSymbol (line 48) | @Override
    method isBottomUp (line 53) | @Override
    method isTopDown (line 58) | @Override
    method isDisk (line 63) | @Override
    method hashCode (line 68) | @Override
    method equals (line 76) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/BuiltInConstructorGetterSymbol.java
  type BuiltInConstructorGetterSymbol (line 33) | public enum BuiltInConstructorGetterSymbol implements ConstructorSymbol {
    method BuiltInConstructorGetterSymbol (line 43) | private BuiltInConstructorGetterSymbol(String name, Type... types) {
    method getArity (line 50) | @Override
    method getCompileTimeType (line 55) | @Override
    method toString (line 60) | @Override
    method getConstructorSymbolType (line 65) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/BuiltInConstructorSymbol.java
  type BuiltInConstructorSymbol (line 42) | public enum BuiltInConstructorSymbol implements ConstructorSymbol {
    method BuiltInConstructorSymbol (line 189) | private BuiltInConstructorSymbol(String name, int arity, ConstructorSy...
    method getArity (line 195) | @Override
    method makeType (line 200) | private FunctorType makeType(Type... types) {
    method getCompileTimeType (line 205) | @Override
    method getConstructorSymbolType (line 303) | @Override
    method toString (line 308) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/BuiltInConstructorTesterSymbol.java
  type BuiltInConstructorTesterSymbol (line 35) | public enum BuiltInConstructorTesterSymbol implements ConstructorSymbol {
    method BuiltInConstructorTesterSymbol (line 54) | private BuiltInConstructorTesterSymbol(String name, Type... types) {
    method getArity (line 61) | @Override
    method getConstructorSymbolType (line 66) | @Override
    method getCompileTimeType (line 71) | @Override
    method toString (line 76) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/BuiltInFunctionSymbol.java
  type BuiltInFunctionSymbol (line 40) | public enum BuiltInFunctionSymbol implements FunctionSymbol {
    method BuiltInFunctionSymbol (line 280) | BuiltInFunctionSymbol(String name, int arity) {
    method getArity (line 285) | @Override
    method getCompileTimeType (line 290) | @Override
    method toString (line 461) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/BuiltInTypeSymbol.java
  type BuiltInTypeSymbol (line 22) | public enum BuiltInTypeSymbol implements TypeSymbol {
    method BuiltInTypeSymbol (line 57) | private BuiltInTypeSymbol(String name, int arity) {
    method getArity (line 62) | @Override
    method getTypeSymbolType (line 67) | @Override
    method toString (line 72) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/ConstructorSymbol.java
  type ConstructorSymbol (line 22) | public interface ConstructorSymbol extends TypedSymbol {
    method getConstructorSymbolType (line 24) | ConstructorSymbolType getConstructorSymbolType();
    method isSolverConstructorSymbol (line 26) | default boolean isSolverConstructorSymbol() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/ConstructorSymbolImpl.java
  class ConstructorSymbolImpl (line 24) | class ConstructorSymbolImpl extends AbstractTypedSymbol implements Const...
    method ConstructorSymbolImpl (line 28) | public ConstructorSymbolImpl(
    method getConstructorSymbolType (line 34) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/ConstructorSymbolType.java
  type ConstructorSymbolType (line 22) | public enum ConstructorSymbolType {

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/FunctionSymbol.java
  type FunctionSymbol (line 22) | public interface FunctionSymbol extends TypedSymbol {}

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/GlobalSymbolManager.java
  class GlobalSymbolManager (line 40) | public final class GlobalSymbolManager {
    method GlobalSymbolManager (line 42) | private GlobalSymbolManager() {
    method hasName (line 51) | public static boolean hasName(String name) {
    method lookup (line 56) | public static Symbol lookup(String name) {
    method lookup (line 60) | public static Symbol lookup(String name, Param... params) {
    method lookup (line 64) | public static Symbol lookup(String name, List<Param> params) {
    method getParameterizedSymbol (line 80) | public static ParameterizedConstructorSymbol getParameterizedSymbol(
    method getParameterizedSymbol (line 85) | public static ParameterizedConstructorSymbol getParameterizedSymbol(
    method getParameterizedSymbolInternal (line 91) | private static ParameterizedConstructorSymbol getParameterizedSymbolIn...
    method checkInitialized (line 97) | private static void checkInitialized() {
    method initialize (line 103) | private static synchronized void initialize() {
    method register (line 116) | private static void register(Symbol[] symbols) {
    method register (line 122) | private static void register(Symbol sym) {
    method register (line 130) | private static void register(BuiltInConstructorSymbolBase[] bases) {
    method createTypeSymbol (line 138) | private static TypeSymbol createTypeSymbol(String name, int arity, Typ...
    method createConstructorSymbol (line 145) | private static ConstructorSymbol createConstructorSymbol(
    method getTypeSymbols (line 153) | public static Set<TypeSymbol> getTypeSymbols() {
    method lookupTupleSymbol (line 161) | public static TupleSymbol lookupTupleSymbol(int arity) {
    method lookupTupleTypeSymbol (line 166) | public static TypeSymbol lookupTupleTypeSymbol(int arity) {
    method instantiateTuple (line 171) | private static void instantiateTuple(int arity) {
    class TupleSymbol (line 203) | public static class TupleSymbol implements ConstructorSymbol {
      method TupleSymbol (line 208) | private TupleSymbol(int arity, FunctorType type) {
      method getCompileTimeType (line 213) | @Override
      method getArity (line 218) | @Override
      method toString (line 223) | @Override
      method getConstructorSymbolType (line 228) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/MutableRelationSymbol.java
  type MutableRelationSymbol (line 22) | public interface MutableRelationSymbol extends RelationSymbol {
    method setTopDown (line 24) | void setTopDown();
    method setBottomUp (line 26) | void setBottomUp();
    method setDisk (line 28) | void setDisk();
    method setEdb (line 30) | void setEdb();

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/PredicateFunctionSymbol.java
  class PredicateFunctionSymbol (line 34) | public class PredicateFunctionSymbol implements FunctionSymbol {
    method create (line 41) | public static synchronized PredicateFunctionSymbol create(
    method createPlaceholder (line 55) | public static synchronized PredicateFunctionSymbol createPlaceholder(
    method createNew (line 66) | private static PredicateFunctionSymbol createNew(
    method PredicateFunctionSymbol (line 100) | private PredicateFunctionSymbol(
    method getArity (line 107) | @Override
    method getCompileTimeType (line 112) | @Override
    method getPredicateSymbol (line 117) | public RelationSymbol getPredicateSymbol() {
    method getBindings (line 121) | public BindingType[] getBindings() {
    method toString (line 125) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/RecordSymbol.java
  type RecordSymbol (line 24) | public interface RecordSymbol extends ConstructorSymbol {
    method getLabels (line 26) | List<FunctionSymbol> getLabels();

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/RelationSymbol.java
  type RelationSymbol (line 22) | public interface RelationSymbol extends TypedSymbol {
    method isIdbSymbol (line 24) | boolean isIdbSymbol();
    method isEdbSymbol (line 26) | default boolean isEdbSymbol() {
    method isDisk (line 30) | boolean isDisk();
    method isBottomUp (line 32) | boolean isBottomUp();
    method isTopDown (line 34) | boolean isTopDown();

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/Symbol.java
  type Symbol (line 22) | public interface Symbol {
    method getArity (line 24) | int getArity();

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/SymbolComparator.java
  type SymbolComparator (line 24) | public enum SymbolComparator implements Comparator<Symbol> {
    method compare (line 27) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/SymbolManager.java
  class SymbolManager (line 39) | public class SymbolManager {
    method createTypeSymbol (line 44) | public TypeSymbol createTypeSymbol(String name, int arity, TypeSymbolT...
    method createConstructorSymbol (line 51) | public ConstructorSymbol createConstructorSymbol(
    method createRecordSymbol (line 59) | public RecordSymbol createRecordSymbol(
    method createFunctionSymbol (line 67) | public FunctionSymbol createFunctionSymbol(String name, int arity, Fun...
    method createRelationSymbol (line 74) | public MutableRelationSymbol createRelationSymbol(String name, int ari...
    method checkNotUsed (line 81) | public void checkNotUsed(String name) {
    method hasName (line 88) | public boolean hasName(String name) {
    method hasConstructorSymbolWithName (line 92) | public boolean hasConstructorSymbolWithName(String name) {
    method lookupSymbol (line 99) | public Symbol lookupSymbol(String name) {
    method getParameterizedSymbol (line 103) | public ParameterizedSymbol getParameterizedSymbol(SymbolBase base) {
    method lookupSymbol (line 110) | public Symbol lookupSymbol(String name, List<Param> params) {
    method createPredicateFunctionSymbol (line 128) | public PredicateFunctionSymbol createPredicateFunctionSymbol(
    method createPredicateFunctionSymbolPlaceholder (line 133) | public PredicateFunctionSymbol createPredicateFunctionSymbolPlaceholde...
    method lookupIndexConstructorSymbol (line 137) | public ConstructorSymbol lookupIndexConstructorSymbol(int index) {
    class FunctionSymbolImpl (line 152) | private static class FunctionSymbolImpl extends AbstractTypedSymbol im...
      method FunctionSymbolImpl (line 154) | public FunctionSymbolImpl(String name, int arity, FunctorType type) {
    class RecordSymbolImpl (line 159) | private static class RecordSymbolImpl extends AbstractTypedSymbol impl...
      method RecordSymbolImpl (line 163) | public RecordSymbolImpl(String name, int arity, FunctorType type, Li...
      method getConstructorSymbolType (line 168) | @Override
      method getLabels (line 173) | @Override
    class RelationSymbolImpl (line 179) | private static class RelationSymbolImpl extends AbstractTypedSymbol
      type Mode (line 182) | private enum Mode {
      method RelationSymbolImpl (line 193) | public RelationSymbolImpl(String name, int arity, FunctorType type) {
      method isIdbSymbol (line 197) | @Override
      method isEdbSymbol (line 202) | @Override
      method isDisk (line 207) | @Override
      method isBottomUp (line 212) | @Override
      method isTopDown (line 217) | @Override
      method setTopDown (line 222) | @Override
      method setBottomUp (line 230) | @Override
      method setDisk (line 238) | @Override
      method setEdb (line 243) | @Override
    method registerSymbol (line 253) | public void registerSymbol(Symbol sym) {
    method getTypeSymbols (line 266) | public Set<TypeSymbol> getTypeSymbols() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/TypeSymbol.java
  type TypeSymbol (line 22) | public interface TypeSymbol extends Symbol {
    method getTypeSymbolType (line 24) | TypeSymbolType getTypeSymbolType();
    method isNormalType (line 26) | default boolean isNormalType() {
    method isAlias (line 30) | default boolean isAlias() {
    method isUninterpretedSort (line 34) | default boolean isUninterpretedSort() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/TypeSymbolImpl.java
  class TypeSymbolImpl (line 22) | class TypeSymbolImpl extends AbstractSymbol implements TypeSymbol {
    method TypeSymbolImpl (line 26) | public TypeSymbolImpl(String name, int arity, TypeSymbolType symType) {
    method getTypeSymbolType (line 31) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/TypeSymbolType.java
  type TypeSymbolType (line 22) | public enum TypeSymbolType {

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/TypedSymbol.java
  type TypedSymbol (line 24) | public interface TypedSymbol extends Symbol {
    method getCompileTimeType (line 26) | FunctorType getCompileTimeType();

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/WrappedRelationSymbol.java
  type WrappedRelationSymbol (line 22) | public interface WrappedRelationSymbol<R extends RelationSymbol> extends...
    method getBaseSymbol (line 24) | R getBaseSymbol();

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/parameterized/AbstractParameterizedSymbol.java
  class AbstractParameterizedSymbol (line 26) | public abstract class AbstractParameterizedSymbol<B extends SymbolBase>
    method AbstractParameterizedSymbol (line 32) | public AbstractParameterizedSymbol(B base, List<Param> args) {
    method getArity (line 51) | @Override
    method toString (line 56) | @Override
    method getBase (line 69) | @Override
    method getArgs (line 74) | @Override
    method isGround (line 79) | @Override
    method hashCode (line 89) | @Override
    method equals (line 98) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/parameterized/BuiltInConstructorSymbolBase.java
  type BuiltInConstructorSymbolBase (line 26) | public enum BuiltInConstructorSymbolBase implements FunctorBase {
    method BuiltInConstructorSymbolBase (line 113) | private BuiltInConstructorSymbolBase(String name, int arity, ParamKind...
    method getArity (line 119) | @Override
    method toString (line 124) | @Override
    method getParamKinds (line 129) | @Override
    method getConstructorSymbolType (line 134) | public ConstructorSymbolType getConstructorSymbolType() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/parameterized/FunctorBase.java
  type FunctorBase (line 22) | public interface FunctorBase extends SymbolBase {}

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/parameterized/Param.java
  class Param (line 31) | public class Param {
    method Param (line 36) | public Param(Type type, ParamKind kind) {
    method check (line 45) | private boolean check() {
    method getType (line 79) | public Type getType() {
    method getKind (line 83) | public ParamKind getKind() {
    method isGround (line 87) | boolean isGround() {
    method wildCards (line 91) | public static List<Param> wildCards(int howMany) {
    method applySubst (line 99) | public static List<Param> applySubst(Iterable<Param> params, Map<TypeV...
    method nat (line 107) | public static Param nat(int index) {
    method nat (line 111) | public static Param nat(Type type) {
    method wildCard (line 115) | public static Param wildCard() {
    method wildCard (line 119) | public static Param wildCard(Type type) {
    method hashCode (line 123) | @Override
    method equals (line 132) | @Override
    method toString (line 145) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/parameterized/ParamKind.java
  type ParamKind (line 22) | public enum ParamKind {

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/parameterized/ParameterizedConstructorSymbol.java
  class ParameterizedConstructorSymbol (line 51) | public class ParameterizedConstructorSymbol
    method ParameterizedConstructorSymbol (line 59) | private ParameterizedConstructorSymbol(BuiltInConstructorSymbolBase ba...
    method mk (line 64) | public static ParameterizedConstructorSymbol mk(
    method expandAsFpAlias (line 137) | private static List<Param> expandAsFpAlias(Param param) {
    method copyWithNewArgs (line 150) | @Override
    method copyWithNewArgs (line 155) | @Override
    method getConstructorSymbolType (line 160) | public ConstructorSymbolType getConstructorSymbolType() {
    method makeType (line 164) | private FunctorType makeType() {
    method getCompileTimeType (line 307) | @Override
    method mkType (line 312) | private static FunctorType mkType(Type... types) {
    method makeFinal (line 316) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/parameterized/ParameterizedSymbol.java
  type ParameterizedSymbol (line 25) | public interface ParameterizedSymbol extends Symbol {
    method getBase (line 27) | SymbolBase getBase();
    method getArgs (line 29) | List<Param> getArgs();
    method copyWithNewArgs (line 31) | ParameterizedSymbol copyWithNewArgs(List<Param> args);
    method copyWithNewArgs (line 33) | ParameterizedSymbol copyWithNewArgs(Param... args);
    method makeFinal (line 35) | ParameterizedSymbol makeFinal();
    method isGround (line 37) | boolean isGround();

FILE: src/main/java/edu/harvard/seas/pl/formulog/symbols/parameterized/SymbolBase.java
  type SymbolBase (line 24) | public interface SymbolBase {
    method getArity (line 26) | int getArity();
    method getParamKinds (line 28) | List<ParamKind> getParamKinds();
    method getNumParams (line 30) | default int getNumParams() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/types/BuiltInTypes.java
  class BuiltInTypes (line 57) | public final class BuiltInTypes {
    method BuiltInTypes (line 59) | private BuiltInTypes() {
    method setCmpConstructors (line 88) | private static void setCmpConstructors() {
    method setListConstructors (line 98) | private static void setListConstructors() {
    method setOptionConstructors (line 108) | private static void setOptionConstructors() {
    method list (line 117) | public static AlgebraicDataType list(Type a) {
    method option (line 121) | public static AlgebraicDataType option(Type a) {
    method smt (line 125) | public static AlgebraicDataType smt(Type a) {
    method sym (line 129) | public static AlgebraicDataType sym(Type a) {
    method bv (line 133) | public static AlgebraicDataType bv(Type a) {
    method bv (line 137) | public static AlgebraicDataType bv(int width) {
    method fp (line 141) | public static AlgebraicDataType fp(Type a, Type b) {
    method fp (line 145) | public static AlgebraicDataType fp(int exponent, int significand) {
    method array (line 149) | public static AlgebraicDataType array(Type a, Type b) {
    method opaqueSet (line 153) | public static AlgebraicDataType opaqueSet(Type a) {
    method pair (line 157) | public static AlgebraicDataType pair(Type a, Type b) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/types/FunctorType.java
  class FunctorType (line 36) | public class FunctorType implements Type {
    method FunctorType (line 41) | public FunctorType(List<Type> argTypes, Type retType) {
    method FunctorType (line 46) | public FunctorType(Type... types) {
    method getArgTypes (line 52) | public List<Type> getArgTypes() {
    method getRetType (line 56) | public Type getRetType() {
    method freshen (line 60) | public FunctorType freshen() {
    method hashCode (line 102) | @Override
    method equals (line 111) | @Override
    method accept (line 126) | @Override
    method applySubst (line 131) | @Override
    method toString (line 138) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/types/IndexedType.java
  type IndexedType (line 25) | public interface IndexedType {
    method instantiate (line 27) | Type instantiate(List<Integer> indices);

FILE: src/main/java/edu/harvard/seas/pl/formulog/types/TypeAlias.java
  class TypeAlias (line 30) | public class TypeAlias {
    method TypeAlias (line 36) | public TypeAlias(TypeSymbol sym, List<TypeVar> params, Type type) {
    method get (line 53) | public static TypeAlias get(TypeSymbol sym, List<TypeVar> params, Type...
    method getSymbol (line 57) | public TypeSymbol getSymbol() {
    method getNumberOfParams (line 61) | public int getNumberOfParams() {
    method getParam (line 65) | public Type getParam(int idx) {
    method toString (line 72) | @Override
    method hashCode (line 90) | @Override
    method equals (line 100) | @Override
    method getParams (line 118) | public List<TypeVar> getParams() {
    method instantiate (line 122) | public Type instantiate(List<Type> paramTypes) {
    method getType (line 133) | public Type getType() {

FILE: src/main/java/edu/harvard/seas/pl/formulog/types/TypeChecker.java
  class TypeChecker (line 47) | public class TypeChecker {
    method TypeChecker (line 52) | public TypeChecker(Program<UserPredicate, BasicRule> prog2) {
    method typeCheck (line 56) | public synchronized WellTypedProgram typeCheck() throws TypeException {
    method typeCheckQuery (line 148) | private UserPredicate typeCheckQuery() throws TypeException {
    method mapFromFutures (line 156) | private static <K, V> Map<K, V> mapFromFutures(Map<K, Future<V>> futur...
    method typeCheckFacts (line 164) | private Map<RelationSymbol, Set<Term[]>> typeCheckFacts(ExecutorServic...
    method typeCheckRules (line 187) | private Map<RelationSymbol, Set<BasicRule>> typeCheckRules(ExecutorSer...
    method typeCheckFunctions (line 210) | private Map<FunctionSymbol, FunctionDef> typeCheckFunctions(ExecutorSe...
    class TypeCheckerContext (line 240) | private class TypeCheckerContext {
      method rewriteTerm (line 247) | private Term rewriteTerm(Term t, Substitution m) throws TypeException {
      method typeCheckFact (line 251) | public Term[] typeCheckFact(RelationSymbol sym, Term[] args) throws ...
      method rewriteLiteral (line 270) | private ComplexLiteral rewriteLiteral(ComplexLiteral l, Substitution...
      method typeCheckQuery (line 294) | public UserPredicate typeCheckQuery(UserPredicate q) throws TypeExce...
      method typeCheckRule (line 308) | public BasicRule typeCheckRule(Rule<UserPredicate, ComplexLiteral> r...
      method makeIndexSubstitution (line 331) | private Substitution makeIndexSubstitution(Map<Var, Type> subst) {
      method typeCheckFunction (line 346) | public UserFunctionDef typeCheckFunction(UserFunctionDef functionDef...
      method processAtoms (line 375) | private void processAtoms(Iterable<ComplexLiteral> atoms, Map<Var, T...
      method genConstraints (line 381) | private void genConstraints(RelationSymbol sym, Term[] args, Map<Var...
      method genConstraints (line 391) | private void genConstraints(ComplexLiteral a, Map<Var, Type> subst) {
      method genConstraints (line 412) | private void genConstraints(UserFunctionDef def, Map<Var, Type> subs...
      method genConstraints (line 417) | private void genConstraints(
      method mkTypeVarsOpaque (line 433) | private Type mkTypeVarsOpaque(Type t, Map<TypeVar, OpaqueType> subst) {
      method genConstraintsForExpr (line 463) | private void genConstraintsForExpr(
      method addConstraint (line 518) | private void addConstraint(Term t, Type t1, Type t2, boolean inFormu...
      method genConstraints (line 527) | private void genConstraints(Term t, Type ttype, Map<Var, Type> subst...
      method genConstraintsForVar (line 558) | private void genConstraintsForVar(Var t, Type ttype, Map<Var, Type> ...
      method genConstraintsForPrimitive (line 573) | private void genConstraintsForPrimitive(Primitive<?> t, Type ttype, ...
      method genConstraintsForConstructor (line 577) | private void genConstraintsForConstructor(
      method genConstraintsForFunctionCall (line 601) | private void genConstraintsForFunctionCall(
      method checkConstraints (line 612) | private boolean checkConstraints() {
      method checkTypesInFormulae (line 626) | private boolean checkTypesInFormulae(Set<Type> types) {
      method checkTypeInFormula (line 635) | private boolean checkTypeInFormula(Type ty) {
      method checkConstraints (line 649) | private boolean checkConstraints(boolean inFormulaContext) {
      method handleVars (line 672) | private boolean handleVars(Type type1, Type type2) {
      method unify (line 696) | private boolean unify(Term t, Type type1, Type type2) {
      method lookupType (line 735) | private Type lookupType(Type t) {
      method visit (line 742) | @Override
      method visit (line 750) | @Override
      method visit (line 775) | @Override
      method visit (line 780) | @Override
      method handleParameterizedSymbol (line 786) | private ParameterizedSymbol handleParameterizedSymbol(ParameterizedS...
      method visit (line 809) | @Override
      method visit (line 821) | @Override
      method visit (line 842) | @Override
      method firstRewritingPass (line 874) | NestedFunctionDef firstRewritingPass(NestedFunctionDef def, Substitu...
      method visit (line 891) | @Override
    method addBinding (line 901) | public static void addBinding(TypeVar x, Type t, Map<TypeVar, Type> su...
    method lookupType (line 915) | public static Type lookupType(Type t, Map<TypeVar, ? extends Type> sub...
    method simplify (line 947) | public static Type simplify(Type t) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/types/TypeException.java
  class TypeException (line 22) | public class TypeException extends Exception {
    method TypeException (line 27) | public TypeException() {}
    method TypeException (line 34) | public TypeException(String message) {
    method TypeException (line 43) | public TypeException(Throwable cause) {
    method TypeException (line 53) | public TypeException(String message, Throwable cause) {
    method TypeException (line 65) | public TypeException(

FILE: src/main/java/edu/harvard/seas/pl/formulog/types/TypeManager.java
  class TypeManager (line 30) | public class TypeManager {
    method registerAlias (line 34) | public void registerAlias(TypeAlias alias) {
    method lookup (line 42) | public Type lookup(TypeSymbol typeSym, List<Type> typeArgs) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/types/Types.java
  class Types (line 44) | public final class Types {
    method Types (line 46) | private Types() {
    type Type (line 50) | public interface Type {
      method accept (line 52) | <I, O> O accept(TypeVisitor<I, O> visitor, I in);
      method applySubst (line 54) | Type applySubst(Map<TypeVar, ? extends Type> subst);
      method freshen (line 56) | Type freshen();
      method isVar (line 58) | default boolean isVar() {
      method isIndex (line 62) | default boolean isIndex() {
    type TypeVisitor (line 67) | public interface TypeVisitor<I, O> {
      method visit (line 69) | O visit(TypeVar typeVar, I in);
      method visit (line 71) | O visit(AlgebraicDataType algebraicType, I in);
      method visit (line 73) | O visit(OpaqueType opaqueType, I in);
      method visit (line 75) | O visit(TypeIndex typeIndex, I in);
    class TypeVar (line 78) | public static class TypeVar implements Type, Comparable<TypeVar> {
      method TypeVar (line 85) | private TypeVar(int id) {
      method get (line 89) | public static TypeVar get(String id) {
      method toString (line 94) | @Override
      method accept (line 99) | @Override
      method hashCode (line 104) | @Override
      method equals (line 112) | @Override
      method applySubst (line 121) | @Override
      method fresh (line 126) | public static TypeVar fresh() {
      method isVar (line 130) | @Override
      method compareTo (line 135) | @Override
      method freshen (line 140) | @Override
    method freshen (line 146) | private static List<Type> freshen(List<Type> types) {
    class AlgebraicDataType (line 150) | public static class AlgebraicDataType implements Type, Iterable<Type> {
      method AlgebraicDataType (line 159) | private AlgebraicDataType(TypeSymbol sym, List<Type> typeArgs) {
      method check (line 165) | private void check() {
      method makeWithFreshArgs (line 216) | public static AlgebraicDataType makeWithFreshArgs(TypeSymbol sym) {
      method make (line 224) | public static AlgebraicDataType make(TypeSymbol sym, Type... typeArg...
      method make (line 228) | public static AlgebraicDataType make(TypeSymbol sym, List<Type> type...
      method setConstructors (line 232) | public static void setConstructors(
      method hasConstructors (line 246) | public boolean hasConstructors() {
      method getConstructors (line 250) | public Set<ConstructorScheme> getConstructors() {
      method getSymbol (line 282) | public TypeSymbol getSymbol() {
      method iterator (line 286) | @Override
      method toString (line 291) | @Override
      method toStringBvOrFp (line 312) | private String toStringBvOrFp() {
      method accept (line 330) | @Override
      method hashCode (line 335) | @Override
      method equals (line 344) | @Override
      method getTypeArgs (line 358) | public List<Type> getTypeArgs() {
      method applySubst (line 362) | @Override
      method freshen (line 371) | @Override
      class ConstructorScheme (line 376) | public static class ConstructorScheme {
        method ConstructorScheme (line 382) | public ConstructorScheme(
        method getSymbol (line 390) | public ConstructorSymbol getSymbol() {
        method getTypeArgs (line 394) | public List<Type> getTypeArgs() {
        method getGetterSymbols (line 398) | public List<ConstructorSymbol> getGetterSymbols() {
        method hashCode (line 402) | @Override
        method equals (line 412) | @Override
    class OpaqueType (line 429) | public static class OpaqueType implements Type {
      method OpaqueType (line 434) | private OpaqueType() {
      method get (line 438) | public static OpaqueType get() {
      method accept (line 442) | @Override
      method applySubst (line 447) | @Override
      method toString (line 452) | @Override
      method freshen (line 457) | @Override
    class TypeIndex (line 463) | public static class TypeIndex implements Type {
      method TypeIndex (line 467) | private TypeIndex(int index) {
      method make (line 471) | public static TypeIndex make(int index) {
      method accept (line 475) | @Override
      method applySubst (line 480) | @Override
      method freshen (line 485) | @Override
      method hashCode (line 490) | @Override
      method equals (line 498) | @Override
      method toString (line 507) | @Override
      method isIndex (line 512) | @Override
      method getIndex (line 517) | public int getIndex() {
      method expandAsFpIndex (line 521) | public List<TypeIndex> expandAsFpIndex() {
    method getTypeVars (line 539) | public static Set<TypeVar> getTypeVars(Type t) {
    method getTypeVars (line 543) | public static Set<TypeVar> getTypeVars(Collection<Type> t) {
    method getTypeVars (line 549) | private static void getTypeVars(Type t, Set<TypeVar> acc) {
    method getTypeVars (line 578) | private static void getTypeVars(Collection<Type> types, Set<TypeVar> a...
    method containsTypeVarOrOpaqueType (line 584) | public static boolean containsTypeVarOrOpaqueType(Type t) {
    method isSmtRepresentable (line 616) | public static boolean isSmtRepresentable(Type t) {
    method mayBePreSmtType (line 673) | public static boolean mayBePreSmtType(Type t) {
    method isTupleType (line 730) | public static boolean isTupleType(Type t) {
    method isSmtVarType (line 738) | public static boolean isSmtVarType(Type t) {

FILE: src/main/java/edu/harvard/seas/pl/formulog/types/WellTypedProgram.java
  type WellTypedProgram (line 26) | public interface WellTypedProgram extends Program<UserPredicate, BasicRu...

FILE: src/main/java/edu/harvard/seas/pl/formulog/unification/EmptySubstitution.java
  type EmptySubstitution (line 26) | public enum EmptySubstitution implements Substitution {
    method put (line 29) | @Override
    method get (line 34) | @Override
    method containsKey (line 39) | @Override
    method iterateKeys (line 44) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/unification/OverwriteSubstitution.java
  class OverwriteSubstitution (line 27) | public class OverwriteSubstitution implements Substitution {
    method OverwriteSubstitution (line 31) | public OverwriteSubstitution() {
    method OverwriteSubstitution (line 35) | private OverwriteSubstitution(Map<Var, Term> m) {
    method put (line 39) | @Override
    method get (line 44) | @Override
    method containsKey (line 50) | @Override
    method iterateKeys (line 55) | @Override
    method copy (line 60) | public OverwriteSubstitution copy() {
    method toString (line 64) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/unification/SimpleSubstitution.java
  class SimpleSubstitution (line 27) | public class SimpleSubstitution implements Substitution {
    method put (line 31) | @Override
    method get (line 36) | @Override
    method containsKey (line 43) | @Override
    method iterateKeys (line 48) | @Override
    method toString (line 53) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/unification/Substitution.java
  type Substitution (line 25) | public interface Substitution {
    method put (line 27) | void put(Var v, Term t);
    method get (line 29) | Term get(Var v);
    method getIfPresent (line 31) | static Term getIfPresent(Term t, Substitution s) {
    method containsKey (line 38) | boolean containsKey(Var v);
    method iterateKeys (line 40) | Iterable<Var> iterateKeys();

FILE: src/main/java/edu/harvard/seas/pl/formulog/unification/Unification.java
  class Unification (line 37) | public final class Unification {
    method Unification (line 39) | private Unification() {
    method canBindVars (line 43) | public static boolean canBindVars(
    method handleNormalAtom (line 63) | private static boolean handleNormalAtom(
    method handleUnifyAtom (line 87) | private static boolean handleUnifyAtom(UnificationPredicate atom, Set<...
    method handleUnifyAtomHelper (line 100) | private static boolean handleUnifyAtomHelper(Term t1, Term t2, Set<Var...

FILE: src/main/java/edu/harvard/seas/pl/formulog/util/AbstractFJPTask.java
  class AbstractFJPTask (line 25) | @SuppressWarnings("serial")
    method AbstractFJPTask (line 30) | protected AbstractFJPTask(CountingFJP exec) {
    method compute (line 34) | @Override
    method doTask (line 44) | public abstract void doTask() throws EvaluationException;

FILE: src/main/java/edu/harvard/seas/pl/formulog/util/CompositeIterable.java
  class CompositeIterable (line 27) | public class CompositeIterable<T> implements Iterable<T> {
    method CompositeIterable (line 31) | public CompositeIterable(Iterable<Iterable<T>> its) {
    method iterator (line 35) | @Override
    class CompositeIterator (line 40) | private final class CompositeIterator implements Iterator<T> {
      method CompositeIterator (line 44) | public CompositeIterator() {
      method load (line 52) | private boolean load() {
      method hasNext (line 63) | @Override
      method next (line 68) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/util/CountingFJP.java
  type CountingFJP (line 24) | public interface CountingFJP {
    method externallyAddTask (line 26) | void externallyAddTask(AbstractFJPTask w);
    method recursivelyAddTask (line 28) | void recursivelyAddTask(AbstractFJPTask w);
    method reportTaskCompletion (line 30) | void reportTaskCompletion();
    method blockUntilFinished (line 32) | void blockUntilFinished();
    method blockUntilFinishedExn (line 34) | default void blockUntilFinishedExn() throws EvaluationException {
    method shutdown (line 41) | void shutdown();
    method fail (line 43) | void fail(EvaluationException cause);
    method hasFailed (line 45) | boolean hasFailed();
    method getFailureCause (line 47) | EvaluationException getFailureCause();
    method getStealCount (line 49) | long getStealCount();

FILE: src/main/java/edu/harvard/seas/pl/formulog/util/CountingFJPImpl.java
  class CountingFJPImpl (line 30) | public class CountingFJPImpl implements CountingFJP {
    method CountingFJPImpl (line 36) | public CountingFJPImpl(int parallelism) {
    method externallyAddTask (line 51) | public void externallyAddTask(AbstractFJPTask w) {
    method recursivelyAddTask (line 60) | public void recursivelyAddTask(AbstractFJPTask w) {
    method reportTaskCompletion (line 70) | public void reportTaskCompletion() {
    method blockUntilFinished (line 78) | public final void blockUntilFinished() {
    method shutdown (line 90) | public final void shutdown() {
    method fail (line 101) | public final void fail(EvaluationException cause) {
    method hasFailed (line 109) | public final boolean hasFailed() {
    method getFailureCause (line 113) | public final EvaluationException getFailureCause() {
    method getStealCount (line 117) | @Override

FILE: src/main/java/edu/harvard/seas/pl/formulog/util/Dataset.java
  class Dataset (line 27) | public class Dataset {
    method addDataPoint (line 31) | public void addDataPoint(double val) {
    method size (line 35) | public int size() {
    method computeSum (line 39) | public double computeSum() {
    method computeMean (line 47) | public double computeMean() {
    method computeStdDev (line 52) | public double computeStdDev() {
    method computeMinMedianMax (line 62) | public List<Double> computeMinMedianMax() {
    method getStatsString (line 75) | public String getStatsString(double multiplier) {
    method getStatsString (line 90) | public String getStatsString() {
Condensed preview — 664 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,579K chars).
[
  {
    "path": ".github/dependabot.yml",
    "chars": 109,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"maven\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/maven.yml",
    "chars": 1078,
    "preview": "# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow executi"
  },
  {
    "path": ".github/workflows/pages.yml",
    "chars": 2039,
    "preview": "# This workflow uses actions that are not certified by GitHub.\n# They are provided by a third-party and are governed by\n"
  },
  {
    "path": ".github/workflows/submit-deps.yml",
    "chars": 549,
    "preview": "# Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive\n\nn"
  },
  {
    "path": ".gitignore",
    "chars": 543,
    "preview": "# Compiled class file\n*.class\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Packa"
  },
  {
    "path": "Dockerfile",
    "chars": 1265,
    "preview": "# To upload the Docker images to Dockerhub, log into the Docker console, and then run\n#\n#   docker buildx build --push -"
  },
  {
    "path": "LICENSE.txt",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 2756,
    "preview": "# Formulog\n\n![Build Status](https://github.com/HarvardPL/formulog/actions/workflows/maven.yml/badge.svg)\n\n**TL;DR: write"
  },
  {
    "path": "changelog.md",
    "chars": 5449,
    "preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\n## [0.8.0] - 2024-10-18\n\n### Added\n\n-"
  },
  {
    "path": "docs/Gemfile",
    "chars": 288,
    "preview": "source 'https://rubygems.org'\n\ngem \"jekyll\", \"~> 4.3.4\" # installed by `gem jekyll`\n# gem \"webrick\"        # required wh"
  },
  {
    "path": "docs/_config.yml",
    "chars": 199,
    "preview": "title: Formulog \ndescription: Datalog for SMT-based static analysis \ntheme: just-the-docs\n\nurl: https://just-the-docs.gi"
  },
  {
    "path": "docs/eval_modes/compile.md",
    "chars": 2164,
    "preview": "---\ntitle: Compilation\nlayout: page\nparent: Evaluation Modes\nnav_order: 3\n---\n\n# Compilation\n\nAs an alternative to being"
  },
  {
    "path": "docs/eval_modes/eager.md",
    "chars": 1486,
    "preview": "---\ntitle: Eager Evaluation\nlayout: page\nparent: Evaluation Modes\nnav_order: 4\n---\n\n# Eager Evaluation\n\nIn addition to t"
  },
  {
    "path": "docs/eval_modes/index.md",
    "chars": 244,
    "preview": "---\ntitle: Evaluation Modes\nlayout: page\nnav_order: 4\n---\n\n# Evaluation Modes\n\nGiven a Formulog program, there are many "
  },
  {
    "path": "docs/eval_modes/options.md",
    "chars": 4434,
    "preview": "---\ntitle: Options and System Properties \nlayout: page\nparent: Evaluation Modes\nnav_order: 1\n---\n\n# Options and System P"
  },
  {
    "path": "docs/eval_modes/smt.md",
    "chars": 1833,
    "preview": "---\ntitle: Solver Modes and Incremental SMT Solving\nlayout: page\nparent: Evaluation Modes\nnav_order: 2\n---\n\n# Solver Mod"
  },
  {
    "path": "docs/index.md",
    "chars": 523,
    "preview": "---\ntitle: Home\nlayout: home\nnav_order: 1\n---\n\n# Welcome to Formulog!\n\nFormulog is a programming language that extends t"
  },
  {
    "path": "docs/lang_ref/goal_directed_eval.md",
    "chars": 3398,
    "preview": "---\ntitle: Goal-Directed Evaluation\nlayout: page\nparent: Language Reference\nnav_order: 3\n---\n\n# Goal-Directed Evaluation"
  },
  {
    "path": "docs/lang_ref/index.md",
    "chars": 447,
    "preview": "---\ntitle: Language Reference\nlayout: page\nnav_order: 5\n---\n\n# Language Reference\n\nThis set of documents describes the F"
  },
  {
    "path": "docs/lang_ref/lang_basics.md",
    "chars": 13530,
    "preview": "---\ntitle: Language Basics\nlayout: page\nparent: Language Reference\nnav_order: 1\n---\n\n# Language Basics\n\nFormulog is an e"
  },
  {
    "path": "docs/lang_ref/logical_formulas.md",
    "chars": 16900,
    "preview": "---\ntitle: Logical Formulas\nlayout: page\nparent: Language Reference\nnav_order: 4\n---\n\n# Logical Formulas\n\nFormulog provi"
  },
  {
    "path": "docs/lang_ref/program_safety.md",
    "chars": 4644,
    "preview": "---\ntitle: Program Safety\nlayout: page\nparent: Language Reference\nnav_order: 2\n---\n\n# Program Safety\n\nFormulog imposes s"
  },
  {
    "path": "docs/pubs.md",
    "chars": 2499,
    "preview": "---\ntitle: Publications and Artifacts\nlayout: page\nnav_order: 6\n---\n\n# Publications and Artifacts\n\nCheck out our academi"
  },
  {
    "path": "docs/starting.md",
    "chars": 4392,
    "preview": "---\ntitle: Getting Started\nlayout: page\nnav_order: 2\n---\n\n# Getting Started\n\nThank you for your interest in Formulog!\nTh"
  },
  {
    "path": "docs/tutorial/index.md",
    "chars": 29907,
    "preview": "---\ntitle: Tutorial\nlayout: page\nnav_order: 3\n---\n\n# Tutorial: Building a Refinement Type Checker\n\nIn this tutorial, we'"
  },
  {
    "path": "examples/greeting.flg",
    "chars": 911,
    "preview": "(*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2018 - 2019 President and Fellows of Harvard College\n * %%\n * Licensed und"
  },
  {
    "path": "examples/liquid_types.flg",
    "chars": 12040,
    "preview": "(*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2018 - 2019 President and Fellows of Harvard College\n * %%\n * Licensed und"
  },
  {
    "path": "examples/symeval.flg",
    "chars": 13830,
    "preview": "(*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2018 - 2019 President and Fellows of Harvard College\n * %%\n * Licensed und"
  },
  {
    "path": "examples/tutorial.flg",
    "chars": 10733,
    "preview": "(***\n\nThis is the full code listing for the Formulog tutorial, which is available at\n<https://harvardpl.github.io/formul"
  },
  {
    "path": "license-header",
    "chars": 665,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) $YEAR President and Fellows of Harvard College\n * %%\n * Licensed under the"
  },
  {
    "path": "misc/flg.vim",
    "chars": 1745,
    "preview": "\" Vim syntax file\n\" Language: Formulog\n\" Maintainer: Aaron Bembenek\n\" Latest Revision: 9 May 2019\n\nif exists(\"b:current_"
  },
  {
    "path": "pom.xml",
    "chars": 4949,
    "preview": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:sch"
  },
  {
    "path": "src/main/antlr4/edu/harvard/seas/pl/formulog/parsing/generated/Formulog.g4",
    "chars": 6189,
    "preview": "grammar Formulog;\n\nprog\n:\n\t(\n\t\tmetadata\n\t\t| stmt\n\t)* EOF\n;\n\ntsvFile\n:\n\ttabSeparatedTermLine* EOF\n;\n\ntabSeparatedTermLine"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/Configuration.java",
    "chars": 24050,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/FormulogTester.java",
    "chars": 11789,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2021-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/Main.java",
    "chars": 14691,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/PrintPreference.java",
    "chars": 786,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/AbstractRule.java",
    "chars": 2469,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/AbstractTerm.java",
    "chars": 909,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/BasicProgram.java",
    "chars": 788,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/BasicRule.java",
    "chars": 1436,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/BindingType.java",
    "chars": 966,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/BoolTerm.java",
    "chars": 2041,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/ComplexLiteral.java",
    "chars": 1459,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/ComplexLiterals.java",
    "chars": 1512,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Constructor.java",
    "chars": 2084,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Constructors.java",
    "chars": 35143,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Expr.java",
    "chars": 1481,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Exprs.java",
    "chars": 1360,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/FP32.java",
    "chars": 2495,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/FP64.java",
    "chars": 2506,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Fold.java",
    "chars": 4242,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/FunctionCallFactory.java",
    "chars": 6902,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Functor.java",
    "chars": 1249,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/I32.java",
    "chars": 2012,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/I64.java",
    "chars": 2010,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/LetFunExpr.java",
    "chars": 4080,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Literal.java",
    "chars": 763,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/MatchClause.java",
    "chars": 4330,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/MatchExpr.java",
    "chars": 5784,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Model.java",
    "chars": 1957,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/NestedFunctionDef.java",
    "chars": 3526,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/OpaqueSet.java",
    "chars": 3129,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2021-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Primitive.java",
    "chars": 1833,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Program.java",
    "chars": 1642,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Rule.java",
    "chars": 1266,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/SmtLibTerm.java",
    "chars": 1074,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/StringTerm.java",
    "chars": 2076,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Term.java",
    "chars": 1555,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Terms.java",
    "chars": 6527,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/UnificationPredicate.java",
    "chars": 2808,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/UserPredicate.java",
    "chars": 3444,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/ast/Var.java",
    "chars": 2634,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/CodeGen.java",
    "chars": 4783,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/CodeGenContext.java",
    "chars": 5720,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/CodeGenException.java",
    "chars": 977,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/CodeGenUtil.java",
    "chars": 4089,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/DeltaFirstQueryPlanner.java",
    "chars": 2445,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2023 President and Fellows of Harvard College\n * %%\n * Licensed under the "
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/FuncsHpp.java",
    "chars": 18965,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/FunctorCodeGen.java",
    "chars": 5731,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/MainCpp.java",
    "chars": 3821,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/MatchCodeGen.java",
    "chars": 15941,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/NopQueryPlanner.java",
    "chars": 1070,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/PatternMatchTree.java",
    "chars": 15279,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/QueryPlanner.java",
    "chars": 1005,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/RuleTranslator.java",
    "chars": 14535,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/SmtParserCpp.java",
    "chars": 6932,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2023 President and Fellows of Harvard College\n * %%\n * Licensed under the "
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/SmtShimCpp.java",
    "chars": 14207,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/SouffleCodeGen.java",
    "chars": 6960,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/SymbolCpp.java",
    "chars": 2597,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/SymbolHpp.java",
    "chars": 1889,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/TemplateSrcFile.java",
    "chars": 1417,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/TermCodeGen.java",
    "chars": 9193,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/TermCpp.java",
    "chars": 2406,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/TypeCodeGen.java",
    "chars": 7923,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/TypeCpp.java",
    "chars": 2751,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppAccess.java",
    "chars": 1393,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppBaseTerm.java",
    "chars": 2888,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppBinop.java",
    "chars": 1991,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppBlock.java",
    "chars": 1262,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppCast.java",
    "chars": 1365,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppConst.java",
    "chars": 1440,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppCtor.java",
    "chars": 2140,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppDecl.java",
    "chars": 1510,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppExpr.java",
    "chars": 1127,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppExprFromString.java",
    "chars": 1061,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppFor.java",
    "chars": 2103,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppForEach.java",
    "chars": 1527,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppFuncCall.java",
    "chars": 1466,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppGoto.java",
    "chars": 1180,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppIf.java",
    "chars": 2434,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppLabel.java",
    "chars": 1173,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppMethodCall.java",
    "chars": 2042,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppNewArray.java",
    "chars": 1228,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppNullptr.java",
    "chars": 894,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppReturn.java",
    "chars": 1350,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppSeq.java",
    "chars": 1505,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppStmt.java",
    "chars": 829,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppSubscript.java",
    "chars": 1198,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppUnop.java",
    "chars": 1414,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppVar.java",
    "chars": 1093,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppVectorLiteral.java",
    "chars": 1287,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/cpp/CppWhile.java",
    "chars": 1404,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SAtom.java",
    "chars": 1593,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SDestructorBody.java",
    "chars": 1564,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SExprBody.java",
    "chars": 1303,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SFunctorBody.java",
    "chars": 965,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SFunctorCall.java",
    "chars": 1561,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SInfixBinaryOpAtom.java",
    "chars": 1188,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SInt.java",
    "chars": 1018,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SIntList.java",
    "chars": 1310,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SIntListType.java",
    "chars": 1639,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SIntType.java",
    "chars": 850,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SLit.java",
    "chars": 945,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SRule.java",
    "chars": 2361,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SRuleMode.java",
    "chars": 790,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/STerm.java",
    "chars": 946,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SType.java",
    "chars": 755,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/codegen/ast/souffle/SVar.java",
    "chars": 1671,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2022-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/db/BindingTypeArrayWrapper.java",
    "chars": 1475,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/db/ExampleComparator.java",
    "chars": 1353,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/db/IndexedFactDb.java",
    "chars": 1375,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/db/IndexedFactDbBuilder.java",
    "chars": 964,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/db/MinChainCover.java",
    "chars": 7253,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/db/MinIndex.java",
    "chars": 2525,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/db/SortedIndexedFactDb.java",
    "chars": 20499,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/db/TupleComparatorGenerator.java",
    "chars": 6517,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/AbstractStratumEvaluator.java",
    "chars": 10860,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/EagerStratumEvaluator.java",
    "chars": 9018,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/EvalUtil.java",
    "chars": 2494,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/Evaluation.java",
    "chars": 1085,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/EvaluationException.java",
    "chars": 1309,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/EvaluationResult.java",
    "chars": 1064,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/IndexedRule.java",
    "chars": 3809,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/PredicateFunctionSetter.java",
    "chars": 9857,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/RoundBasedStratumEvaluator.java",
    "chars": 11602,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/SemiNaiveEvaluation.java",
    "chars": 23342,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/SemiNaiveRule.java",
    "chars": 3525,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/SmtCallFinder.java",
    "chars": 4449,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/StratumEvaluator.java",
    "chars": 799,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/eval/UncheckedEvaluationException.java",
    "chars": 1371,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/functions/BuiltInFunctionDefFactory.java",
    "chars": 49609,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/functions/DummyFunctionDef.java",
    "chars": 1456,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/functions/FunctionDef.java",
    "chars": 1010,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/functions/FunctionDefManager.java",
    "chars": 2475,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/functions/OpaqueSetOps.java",
    "chars": 5886,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2021-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/functions/PredicateFunctionDef.java",
    "chars": 894,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/functions/PrimitiveConversions.java",
    "chars": 7619,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/functions/RecordAccessor.java",
    "chars": 1448,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/functions/UserFunctionDef.java",
    "chars": 2353,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/magic/AdornedSymbol.java",
    "chars": 2849,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/magic/Adornments.java",
    "chars": 5266,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/magic/MagicSetTransformer.java",
    "chars": 32753,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/FactFileParser.java",
    "chars": 1910,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/Identifier.java",
    "chars": 1392,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/ParseException.java",
    "chars": 1526,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/Parser.java",
    "chars": 5704,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/ParsingContext.java",
    "chars": 2344,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/ParsingUtil.java",
    "chars": 4546,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/TermExtractor.java",
    "chars": 36624,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2024 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/TopLevelParser.java",
    "chars": 22292,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/TypeExtractor.java",
    "chars": 6458,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/UncheckedParseException.java",
    "chars": 1458,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/VariableCheckPass.java",
    "chars": 11112,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/parsing/VariableCheckPassException.java",
    "chars": 929,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/AbstractSmtLibSolver.java",
    "chars": 6537,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/BestMatchSmtManager.java",
    "chars": 3328,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/BoolectorProcessFactory.java",
    "chars": 1650,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/CallAndResetSolver.java",
    "chars": 1902,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/CheckSatAssumingSolver.java",
    "chars": 4852,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/Cvc4ProcessFactory.java",
    "chars": 1634,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/DoubleCheckingSolver.java",
    "chars": 1900,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/ExternalSolverProcessFactory.java",
    "chars": 855,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/NotThreadSafeQueueSmtManager.java",
    "chars": 2029,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/PerThreadSmtManager.java",
    "chars": 2150,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/PushPopNaiveSolver.java",
    "chars": 1887,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/PushPopSolver.java",
    "chars": 3215,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/QueueSmtManager.java",
    "chars": 2155,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/SingleShotSolver.java",
    "chars": 2121,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2020-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  },
  {
    "path": "src/main/java/edu/harvard/seas/pl/formulog/smt/SmtLibParser.java",
    "chars": 15662,
    "preview": "/*-\n * #%L\n * Formulog\n * %%\n * Copyright (C) 2019-2023 President and Fellows of Harvard College\n * %%\n * Licensed under"
  }
]

// ... and 464 more files (download for full content)

About this extraction

This page contains the full source code of the HarvardPL/formulog GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 664 files (1.4 MB), approximately 399.4k tokens, and a symbol index with 3392 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!