├── .github └── workflows │ ├── static.yml │ └── test_deduce.yml ├── .gitignore ├── Deduce.lark ├── LICENSE ├── Makefile ├── README.md ├── TODO.md ├── abstract_syntax.py ├── alist.py ├── deduce.py ├── docs ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── bug-report.md ├── code-contribution.md ├── enhancements.md └── knowledge-base │ ├── abstract-syntax.md │ ├── how-it-works.md │ ├── site-maintenance.md │ └── what-to-update.md ├── edit_distance.py ├── entangled.toml ├── error.py ├── example.pf ├── gh_pages ├── 404.html ├── README.md ├── css │ ├── normalize.css │ ├── stdlib-dev.css │ ├── stdlib.css │ ├── style-dev.css │ └── style.css ├── doc │ ├── CheatSheet.md │ ├── FunctionalProgramming.md │ ├── GettingStarted.md │ ├── Index.md │ ├── ProofIntro.md │ ├── Reference.md │ ├── StandardLib.md │ ├── SyntaxGrammar.md │ ├── convert.py │ ├── index_generate.py │ └── lib_generate.py ├── images │ └── logo.svg ├── index.html ├── js │ ├── cache.js │ ├── code.js │ ├── codeUtils.js │ ├── sandbox.js │ ├── script.js │ └── stdlib.js ├── requirements.txt └── sandbox.html ├── lib ├── Base.pf ├── Int.pf ├── List.pf ├── Log.pf ├── Maps.pf ├── MultiSet.pf ├── Nat.pf ├── Option.pf ├── Pair.pf ├── Set.pf ├── Sums.pf └── UInt.pf ├── live_code_vercel_api ├── api.py ├── image-1.png ├── image-2.png ├── image-3.png ├── image.png ├── requirements.txt └── setup.md ├── logos ├── Alt-Logo-1.svg ├── Alt-Logo-2.svg ├── Logo.svg └── Main-Logo.svg ├── parser.py ├── proof_checker.py ├── rec_desc_parser.py ├── requirements.txt ├── test-deduce.py ├── test ├── parse │ ├── all_dot.pf │ ├── all_dot.pf.err │ ├── apply.pf │ ├── apply.pf.err │ ├── array1.pf │ ├── array1.pf.err │ ├── array2.pf │ ├── array2.pf.err │ ├── array3.pf │ ├── array3.pf.err │ ├── call1.pf │ ├── call1.pf.err │ ├── call2_comma.pf │ ├── call2_comma.pf.err │ ├── cases1.pf │ ├── cases1.pf.err │ ├── cases2.pf │ ├── cases2.pf.err │ ├── conclude.pf │ ├── conclude.pf.err │ ├── conjunct1.pf │ ├── conjunct1.pf.err │ ├── conjunct2.pf │ ├── conjunct2.pf.err │ ├── define_1.pf │ ├── define_1.pf.err │ ├── define_term1.pf │ ├── define_term1.pf.err │ ├── define_term2.pf │ ├── define_term2.pf.err │ ├── eof_def.pf │ ├── eof_def.pf.err │ ├── eof_def_1.pf │ ├── eof_def_1.pf.err │ ├── eof_have_0.pf │ ├── eof_have_0.pf.err │ ├── eof_have_1.pf │ ├── eof_have_1.pf.err │ ├── eof_have_2.pf │ ├── eof_have_2.pf.err │ ├── eof_have_3.pf │ ├── eof_have_3.pf.err │ ├── eof_proof.pf │ ├── eof_proof.pf.err │ ├── eof_term.pf │ ├── eof_term.pf.err │ ├── fun_1.pf │ ├── fun_1.pf.err │ ├── fun_2.pf │ ├── fun_2.pf.err │ ├── generic_1.pf │ ├── generic_1.pf.err │ ├── generic_2.pf │ ├── generic_2.pf.err │ ├── hash_term.pf │ ├── hash_term.pf.err │ ├── have_no_by.pf │ ├── have_no_by.pf.err │ ├── have_no_colon.pf │ ├── have_no_colon.pf.err │ ├── id_eof_thm.pf │ ├── id_eof_thm.pf.err │ ├── id_miss.pf │ ├── id_miss.pf.err │ ├── if_no_then.pf │ ├── if_no_then.pf.err │ ├── inst-term-angle-bracket.pf │ ├── inst-term-angle-bracket.pf.err │ ├── instant1.pf │ ├── instant1.pf.err │ ├── instant2.pf │ ├── instant2.pf.err │ ├── list1.pf │ ├── list1.pf.err │ ├── misspell.pf │ ├── misspell.pf.err │ ├── no_term.pf │ ├── no_term.pf.err │ ├── paren_term.pf │ ├── paren_term.pf.err │ ├── pf_brace.pf │ ├── pf_brace.pf.err │ ├── pf_paren.pf │ ├── pf_paren.pf.err │ ├── plus_int.pf │ ├── plus_int.pf.err │ ├── proof_args_comma.pf │ ├── proof_args_comma.pf.err │ ├── proof_brace.pf │ ├── proof_brace.pf.err │ ├── proof_define.pf │ ├── proof_define.pf.err │ ├── proof_paren.pf │ ├── proof_paren.pf.err │ ├── some_dot.pf │ ├── some_dot.pf.err │ ├── suffices1.pf │ ├── suffices1.pf.err │ ├── switch1.pf │ ├── switch1.pf.err │ ├── switch2.pf │ ├── switch2.pf.err │ ├── switch_pf1.pf │ ├── switch_pf1.pf.err │ ├── switch_pf2.pf │ ├── switch_pf2.pf.err │ ├── switch_pf3.pf │ ├── switch_pf3.pf.err │ ├── switch_pf4.pf │ ├── switch_pf4.pf.err │ ├── switch_pf5.pf │ ├── switch_pf5.pf.err │ ├── ty_params_1.pf │ ├── ty_params_1.pf.err │ ├── weird_if.pf │ └── weird_if.pf.err ├── should-error │ ├── advice_and.pf │ ├── advice_and.pf.err │ ├── advice_conclude_given.pf │ ├── advice_conclude_given.pf.err │ ├── advice_false.pf │ ├── advice_false.pf.err │ ├── advice_or.pf │ ├── advice_or.pf.err │ ├── advice_recall.pf │ ├── advice_recall.pf.err │ ├── advice_some.pf │ ├── advice_some.pf.err │ ├── advice_true.pf │ ├── advice_true.pf.err │ ├── all4.pf │ ├── all4.pf.err │ ├── all5.pf │ ├── all5.pf.err │ ├── all_intro_advice1.pf │ ├── all_intro_advice1.pf.err │ ├── all_intro_advice2.pf │ ├── all_intro_advice2.pf.err │ ├── all_intro_advice3.pf │ ├── all_intro_advice3.pf.err │ ├── apply_to_error.pf │ ├── apply_to_error.pf.err │ ├── array2.pf │ ├── array2.pf.err │ ├── block_comment.pf │ ├── block_comment.pf.err │ ├── cases_error.pf │ ├── cases_error.pf.err │ ├── comma_question.pf │ ├── comma_question.pf.err │ ├── conclude.pf │ ├── conclude.pf.err │ ├── conjunct.pf │ ├── conjunct.pf.err │ ├── deep_error.pf │ ├── deep_error.pf.err │ ├── def_generic_terminst.pf │ ├── def_generic_terminst.pf.err │ ├── def_proof_var.pf │ ├── def_proof_var.pf.err │ ├── define_missing_semi.pf │ ├── define_missing_semi.pf.err │ ├── define_proof_missing_term.pf │ ├── define_proof_missing_term.pf.err │ ├── define_type.pf │ ├── define_type.pf.err │ ├── definition1.pf │ ├── definition1.pf.err │ ├── double_private.pf │ ├── double_private.pf.err │ ├── equality.pf │ ├── equality.pf.err │ ├── eval-goal2.pf │ ├── eval-goal2.pf.err │ ├── fn_missing_arrow.pf │ ├── fn_missing_arrow.pf.err │ ├── foldr_sum.pf │ ├── foldr_sum.pf.err │ ├── forgot_def.pf │ ├── forgot_def.pf.err │ ├── forgot_def_pvar.pf │ ├── forgot_def_pvar.pf.err │ ├── forgot_def_rec.pf │ ├── forgot_def_rec.pf.err │ ├── forgot_replace_all.pf │ ├── forgot_replace_all.pf.err │ ├── forgot_replace_allelim.pf │ ├── forgot_replace_allelim.pf.err │ ├── forgot_replace_recall.pf │ ├── forgot_replace_recall.pf.err │ ├── function_case_missing_equal.pf │ ├── function_case_missing_equal.pf.err │ ├── function_not_union.pf.err │ ├── have_remove_marks.pf │ ├── have_remove_marks.pf.err │ ├── help1.pf │ ├── help1.pf.err │ ├── help2.pf │ ├── help2.pf.err │ ├── help3.pf │ ├── help3.pf.err │ ├── help4.pf │ ├── help4.pf.err │ ├── iff_precedence.pf │ ├── iff_precedence.pf.err │ ├── import_lemma.pf │ ├── import_lemma.pf.err │ ├── induction2.pf │ ├── induction2.pf.err │ ├── induction_advice_partial.pf │ ├── induction_advice_partial.pf.err │ ├── induction_case.pf │ ├── induction_case.pf.err │ ├── injective1.pf │ ├── injective1.pf.err │ ├── inst-type-square-bracket.pf │ ├── inst-type-square-bracket.pf.err │ ├── inst_type_forget.pf │ ├── inst_type_forget.pf.err │ ├── int2.pf │ ├── int2.pf.err │ ├── int_error_for_now.pf.err │ ├── lambda_synth.pf │ ├── lambda_synth.pf.err │ ├── len_termination.pf │ ├── len_termination.pf.err │ ├── length_drop.pf │ ├── length_drop.pf.err │ ├── missing-colon-in-have.pf │ ├── missing-colon-in-have.pf.err │ ├── missing-conclusion-subproof.pf │ ├── missing-conclusion-subproof.pf.err │ ├── missing-conclusion.pf │ ├── missing-conclusion.pf.err │ ├── missing-conclusion1.pf │ ├── missing-conclusion1.pf.err │ ├── missing_generic.pf │ ├── missing_generic.pf.err │ ├── missing_recall.pf │ ├── missing_recall.pf.err │ ├── mutual_termination.pf │ ├── mutual_termination.pf.err │ ├── noimport1.pf │ ├── noimport1.pf.err │ ├── noimport2.pf │ ├── noimport2.pf.err │ ├── noimport3.pf │ ├── noimport3.pf.err │ ├── noimport4.pf │ ├── noimport4.pf.err │ ├── opaque_define_use_in_theorem.pf │ ├── opaque_define_use_in_theorem.pf.err │ ├── opaque_evaluate.pf │ ├── opaque_evaluate.pf.err │ ├── opaque_genrec_use_in_theorem.pf │ ├── opaque_genrec_use_in_theorem.pf.err │ ├── opaque_induction.pf │ ├── opaque_induction.pf.err │ ├── opaque_recursive_use_in_theorem.pf │ ├── opaque_recursive_use_in_theorem.pf.err │ ├── opaque_union_pattern_matching.pf │ ├── opaque_union_pattern_matching.pf.err │ ├── opaque_union_use_in_theorem.pf │ ├── opaque_union_use_in_theorem.pf.err │ ├── overload2.pf │ ├── overload2.pf.err │ ├── overload4.pf │ ├── overload4.pf.err │ ├── overload6.pf │ ├── overload6.pf.err │ ├── overload_fail.pf │ ├── overload_fail.pf.err │ ├── paren_term.pf │ ├── paren_term.pf.err │ ├── prefix_operator.pf │ ├── prefix_operator.pf.err │ ├── print_precedence_assoc.pf │ ├── print_precedence_assoc.pf.err │ ├── private_opaque.pf │ ├── private_opaque.pf.err │ ├── recursive_clause_name_mismatch.pf │ ├── recursive_clause_name_mismatch.pf.err │ ├── recursive_import_one.pf │ ├── recursive_import_one.pf.err │ ├── recursive_import_two.pf │ ├── recursive_import_two.pf.err │ ├── reduce_all.pf │ ├── reduce_all.pf.err │ ├── reflexive_not_equality.pf │ ├── reflexive_not_equality.pf.err │ ├── remains_to_prove.pf │ ├── remains_to_prove.pf.err │ ├── remains_to_prove_def.pf │ ├── remains_to_prove_def.pf.err │ ├── replace_match_failure.pf │ ├── replace_match_failure.pf.err │ ├── shadow_warn1.pf │ ├── shadow_warn1.pf.err │ ├── shadow_warn2.pf │ ├── shadow_warn2.pf.err │ ├── shadow_warn3.pf │ ├── shadow_warn3.pf.err │ ├── shadow_warn4.pf │ ├── shadow_warn4.pf.err │ ├── suffices_evaluate.pf │ ├── suffices_evaluate.pf.err │ ├── suffices_implies_hole.pf │ ├── suffices_implies_hole.pf.err │ ├── suffices_misspell.pf │ ├── suffices_misspell.pf.err │ ├── suffices_omitted.pf │ ├── suffices_omitted.pf.err │ ├── sum_append.pf │ ├── sum_append.pf.err │ ├── sum_def.pf │ ├── sum_def.pf.err │ ├── sum_foldr.pf │ ├── sum_foldr.pf.err │ ├── sum_foldr_switch.pf │ ├── sum_foldr_switch.pf.err │ ├── switch_case_close.pf │ ├── switch_case_close.pf.err │ ├── switch_case_empty.pf │ ├── switch_case_empty.pf.err │ ├── switch_case_open.pf │ ├── switch_case_open.pf.err │ ├── switch_case_pattern.pf │ ├── switch_case_pattern.pf.err │ ├── switch_term_error.pf │ ├── switch_term_error.pf.err │ ├── term_inst_foldr.pf │ ├── term_inst_foldr.pf.err │ ├── term_inst_length_node.pf │ ├── term_inst_length_node.pf.err │ ├── theorem_and5.pf │ ├── theorem_and5.pf.err │ ├── theorem_and6.pf │ ├── theorem_and6.pf.err │ ├── theorem_implies5.pf │ ├── theorem_implies5.pf.err │ ├── theorem_implies6.pf │ ├── theorem_implies6.pf.err │ ├── theorem_implies8.pf │ ├── theorem_implies8.pf.err │ ├── theorem_implies_7.pf │ ├── theorem_implies_7.pf.err │ ├── theorem_misspelled.pf │ ├── theorem_misspelled.pf.err │ ├── theorem_or3.pf │ ├── theorem_or3.pf.err │ ├── theorem_or4.pf │ ├── theorem_or4.pf.err │ ├── theorem_true_error.pf │ ├── theorem_true_error.pf.err │ ├── transitive1.pf │ ├── transitive1.pf.err │ ├── unclosed_comment.pf │ ├── unclosed_comment.pf.err │ ├── union_bad_constructor.pf │ ├── union_bad_constructor.pf.err │ ├── union_missing_name.pf │ ├── union_missing_name.pf.err │ ├── use_private_define.pf │ ├── use_private_define.pf.err │ ├── use_private_function.pf │ ├── use_private_function.pf.err │ ├── use_private_union.pf │ └── use_private_union.pf.err ├── should-validate │ ├── ImportTests.pf │ ├── IntTests.pf │ ├── ListTests.pf │ ├── LogTests.pf │ ├── NatTests.pf │ ├── after.pf │ ├── all1.pf │ ├── all2.pf │ ├── all3.pf │ ├── append_assoc.pf │ ├── array1.pf │ ├── array3.pf │ ├── assoc1.pf │ ├── assoc2.pf │ ├── assoc3.pf │ ├── bicond1.pf │ ├── bicond2.pf │ ├── bicond3.pf │ ├── bicond4.pf │ ├── bintree.pf │ ├── comp_switchcase.pf │ ├── conditional1.pf │ ├── define_cases.pf │ ├── definition_in.pf │ ├── empty_file.pf │ ├── eval-fact.pf │ ├── eval-goal.pf │ ├── fib.pf │ ├── fib_switch.pf │ ├── fun1.pf │ ├── fun_zero_param.pf │ ├── function1.pf │ ├── function2.pf │ ├── generic-fun.pf │ ├── generic-fun2.pf │ ├── generic-syth.pf │ ├── generic1.pf │ ├── generic2.pf │ ├── implicit_modus_ponens.pf │ ├── induction1.pf │ ├── induction_auto_assume.pf │ ├── inst1.pf │ ├── inst2.pf │ ├── inst3.pf │ ├── inst4.pf │ ├── inst5.pf │ ├── int1.pf │ ├── list1.pf │ ├── list2.pf │ ├── mark1.pf │ ├── mark2.pf │ ├── mark3.pf │ ├── not_equal.pf │ ├── opaque_define.pf │ ├── opaque_genrec_fun.pf │ ├── opaque_print.pf │ ├── opaque_rec_fun.pf │ ├── opaque_union.pf │ ├── overload1.pf │ ├── overload3.pf │ ├── overload5.pf │ ├── overload_and_definition.pf │ ├── postulate1.pf │ ├── private_define.pf │ ├── private_function.pf │ ├── private_union.pf │ ├── rec1.pf │ ├── rec2.pf │ ├── recall1.pf │ ├── replace_generic.pf │ ├── rewrite_all_mark.pf │ ├── rewrite_with_all.pf │ ├── some1.pf │ ├── some2.pf │ ├── suffices1.pf │ ├── suffices_def.pf │ ├── suffices_implies_omitted.pf │ ├── suffices_omitted.pf │ ├── suffices_rewrite.pf │ ├── switch_auto_assume.pf │ ├── switch_auto_assume_bool.pf │ ├── switch_case_alpha.pf │ ├── switch_term.pf │ ├── theorem_and.pf │ ├── theorem_and2.pf │ ├── theorem_and3.pf │ ├── theorem_and4.pf │ ├── theorem_false1.pf │ ├── theorem_false2.pf │ ├── theorem_false3.pf │ ├── theorem_iff.pf │ ├── theorem_implies.pf │ ├── theorem_implies2.pf │ ├── theorem_implies3.pf │ ├── theorem_implies4.pf │ ├── theorem_implies_mult.pf │ ├── theorem_let.pf │ ├── theorem_or.pf │ ├── theorem_or2.pf │ └── theorem_true.pf └── test-imports │ ├── OpaqueTests.pf │ └── Private.pf └── vercel.json /.github/workflows/test_deduce.yml: -------------------------------------------------------------------------------- 1 | name: Run Tests 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: checkout repo content 15 | uses: actions/checkout@v2 # checkout the repository content to github runner. 16 | - name: setup python 17 | uses: actions/setup-python@v2 18 | with: 19 | python-version: 3.12 #install the python needed 20 | - name: Install dependencies 21 | run: | 22 | python -m pip install --upgrade pip 23 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 24 | if [ -f ./gh_pages/requirements.txt ]; then pip install -r ./gh_pages/requirements.txt; fi 25 | - name: execute py script # run file 26 | run: | 27 | python test-deduce.py --site 28 | python test-deduce.py 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # pycache 2 | __pycache__ 3 | lark/__pycache__ 4 | lark/parsers/__pycache__ 5 | 6 | # personal files 7 | personal 8 | 9 | # test theorems and generated proofs 10 | test/**/*.thm 11 | test/**/doc_*.pf 12 | lib/*.thm 13 | 14 | # vscode files 15 | .vscode 16 | 17 | # release 18 | deduce-release.zip 19 | 20 | # Generated content for site 21 | gh_pages/pages 22 | gh_pages/deduce-code 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PYTHON = $(shell command -v python3.13) 2 | 3 | LIB_DIR = ./lib 4 | TEST_PASS_DIR = ./test/should-validate 5 | TEST_ERROR_DIR = ./test/should-error 6 | 7 | default: tests tests-lib 8 | 9 | tests-should-validate: 10 | $(PYTHON) ./deduce.py --recursive-descent $(TEST_PASS_DIR) --dir $(LIB_DIR) 11 | $(PYTHON) ./deduce.py --lalr $(TEST_PASS_DIR) --dir $(LIB_DIR) 12 | 13 | tests-should-error: 14 | $(PYTHON) ./deduce.py --recursive-descent $(TEST_ERROR_DIR) --error --dir $(LIB_DIR) 15 | $(PYTHON) ./deduce.py --lalr $(TEST_ERROR_DIR) --error --dir $(LIB_DIR) 16 | 17 | tests-lib: 18 | $(PYTHON) ./deduce.py ./lib --recursive-descent --dir $(LIB_DIR) 19 | $(PYTHON) ./deduce.py ./lib --lalr --dir $(LIB_DIR) 20 | 21 | tests: tests-should-validate tests-should-error 22 | 23 | package: 24 | $(PYTHON) ./deduce.py ./lib 25 | mkdir deduce 26 | cp -r lib deduce 27 | cp abstract_syntax.py deduce 28 | cp alist.py deduce 29 | cp Deduce.lark deduce 30 | cp deduce.py deduce 31 | cp edit_distance.py deduce 32 | cp error.py deduce 33 | cp parser.py deduce 34 | cp proof_checker.py deduce 35 | cp example.pf deduce 36 | cp README.md deduce 37 | cp rec_desc_parser.py deduce 38 | zip "deduce-release" -r deduce 39 | rm -rf deduce 40 | rm -f ./lib/*.thm 41 | 42 | clean: 43 | rm -f *~ ./lib/*~ ./test/should-validate/*~ ./test/should-error/*~ 44 | rm -f ./lib/*.thm 45 | rm -f ./test/should-validate/*.thm 46 | rm -f deduce-release.zip 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Deduce](https://jsiek.github.io/deduce/) 2 | 3 | ![Blue Hippo next to the word Deduce.](/logos/Main-Logo.svg) 4 | 5 | The web page for Deduce is at the following link: 6 | 7 | **[https://jsiek.github.io/deduce/](https://jsiek.github.io/deduce/)** 8 | 9 | The directory structure: 10 | * `/docs` Documentation for contributing to Deduce 11 | * `/gh_pages` Source code for the [Deduce website](https://jsiek.github.io/deduce/) 12 | * `/lib` Deduce library files. This includes Nat, List, etc. 13 | * `/live_code_vercel_api` Source code for [Deduce live code](https://jsiek.github.io/deduce/sandbox.html) 14 | * `/logos` The Hippopotamus logo and other images. 15 | * `/test` Deduce files used for testing Deduce. 16 | 17 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | [ ] generalize precedence to everything, e.g. to fix printing of 2 | parentheses in 'all'. 3 | 4 | [ ] equations for ≤, etc. (anything with transitivity) 5 | 6 | [ ] hide the suc-oriented arithmetic 7 | 8 | [ ] rewrite with all-quantified equations 9 | 10 | [ ] add section on rewrite-in to the introduction 11 | 12 | [ ] Revisit syntax for rewriting with a set of equations (replace bar) 13 | 14 | [ ] Display overview of test results after running 15 | 16 | [ ] create more student exercises 17 | 18 | [ ] specify number of unfoldings in definition 19 | 20 | [ ] remove parent param from parser, not needed anymore 21 | 22 | . -------------------------------------------------------------------------------- /alist.py: -------------------------------------------------------------------------------- 1 | def nth(ls, i): 2 | while i != 0 and ls: 3 | i -= 1 4 | ls = ls[1] 5 | return ls 6 | 7 | def cons(val, ls): 8 | return (val, ls) 9 | 10 | def alist_index(ls, key): 11 | index = 0 12 | while ls: 13 | if key == ls[0][0]: 14 | return index 15 | else: 16 | ls = ls[1] 17 | index += 1 18 | return None 19 | 20 | def alist_items(ls): 21 | if ls: 22 | return [ ls[0] ] + alist_items(ls[1]) 23 | else: 24 | return [] 25 | 26 | def alist_keys(ls): 27 | if ls: 28 | return [ ls[0][0] ] + alist_keys(ls[1]) 29 | else: 30 | return [] 31 | 32 | def str_of_alist(ls): 33 | return '{' + ', '.join([str(k) + ': ' + str(v) \ 34 | for (k,v) in alist_items(ls)]) + '}' 35 | -------------------------------------------------------------------------------- /docs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Deduce 2 | 3 | First off, thank you for taking the time to contribute! 4 | 5 | All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. 6 | 7 | ## Table of contents 8 | 9 | - [Code of conduct](#code-of-conduct) 10 | - [I Have a Question](#i-have-a-question) 11 | - [Reporting Bugs](./bug-report.md) 12 | - [Suggesting Enhancements](./enhancements.md) 13 | - [Your First Code Contribution](#your-first-code-contribution) 14 | - [Join The Project Team](#join-the-project-team) 15 | 16 | ## Code of conduct 17 | 18 | This project and everyone participating in it is governed by the [Deduce Code of Conduct](./CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [Jeremy Siek](https://github.com/jsiek) ([jsiek@iu.edu](mailto:jsiek@iu.edu)). 19 | 20 | ## I have a question 21 | 22 | Before you ask a question, it is best to search for existing [issues](https://github.com/jsiek/deduce/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. 23 | 24 | If you then still feel the need to ask a question and need clarification, we recommend the following: 25 | 26 | - Open an [issue](https://github.com/jsiek/deduce/issues/new). 27 | - Provide as much context as you can about what you're running into. 28 | 29 | We will then take care of the issue as soon as possible. 30 | 31 | ## I want to contribute 32 | 33 | Please refer to the following pages for contributing: 34 | 35 | - [Reporting bugs](./bug-report.md) 36 | - [Suggesting enhancements](./enhancements.md) 37 | - [Contributing code](./code-contribution.md) 38 | 39 | ## Join The Project Team 40 | 41 | We're so glad that you're interested in joining the team! Deduce is mainly developed by a small team developers passionate about proof checking and programming languages education. Please send an email to [Jeremy Siek](https://github.com/jsiek) ([jsiek@iu.edu](mailto:jsiek@iu.edu)) to express your interest and have a deeper role in Deduce development. 42 | 43 | ## Attribution 44 | This guide is based on the **contributing.md**. [Make your own](https://contributing.md/)! 45 | -------------------------------------------------------------------------------- /docs/bug-report.md: -------------------------------------------------------------------------------- 1 | # Reporting bugs 2 | 3 | This section guides you through submitting an bug reports for Deduce. 4 | 5 | ### Before submitting a bug report 6 | 7 | Please complete the following steps in advance to help us fix any potential bug as fast as possible. 8 | 9 | - Make sure that you are using the latest version. 10 | - Please make sure to specify whether you are using the [latest Deduce release](https://github.com/jsiek/deduce/releases) or the [main development branch](https://github.com/jsiek/deduce/tree/main). 11 | - Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://jsiek.github.io/deduce/). If you are looking for support, you might want to check [this section](#i-have-a-question)). 12 | - To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](issues?q=label%3Abug). 13 | - Collect information about the bug: 14 | - Stack trace (Traceback) 15 | - Please note whether this is a Deduce error message or a python error message. 16 | - OS, Platform and Version (Windows, Linux, macOS, x86, ARM) 17 | - Python version 18 | 19 | 20 | ### How do I submit a good bug report? 21 | 22 | We use GitHub issues to track bugs and errors. If you run into an issue with the project: 23 | 24 | - Open an [Issue](/issues/new). 25 | - Explain the behavior you would expect and the actual behavior. 26 | - Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. 27 | - Provide the information you collected in the previous section. -------------------------------------------------------------------------------- /docs/enhancements.md: -------------------------------------------------------------------------------- 1 | # Suggesting enhancements 2 | 3 | This section guides you through submitting an enhancement suggestion for Deduce, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. 4 | 5 | ### Before submitting an enhancement 6 | 7 | - Make sure that you are using the [latest version](https://github.com/jsiek/deduce/tree/main). 8 | - Read the [documentation](https://jsiek.github.io/deduce/) carefully and find out if the functionality is already covered, maybe by an individual configuration. 9 | - Perform a [search](/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. 10 | - Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. 11 | 12 | ### How do I submit a good enhancement suggestion? 13 | 14 | Enhancement suggestions are tracked as [GitHub issues](/issues). 15 | 16 | - Use a **clear and descriptive title** for the issue to identify the suggestion. 17 | - Provide a **step-by-step description of the suggested enhancement** in as many details as possible. 18 | - **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you. 19 | - **Explain why this enhancement would be useful** to most Deduce users. You may also want to point out the other projects that solved it better and which could serve as inspiration. -------------------------------------------------------------------------------- /docs/knowledge-base/how-it-works.md: -------------------------------------------------------------------------------- 1 | # How it works 2 | 3 | This file contains a detailed explanation of how Deduce *actually* works. This file will explain the source code and how Deduce goes from a text file to the glorious `file.pf is valid` message. 4 | 5 | ## TODO: Entry point, `deduce.py`, `deduce_file`, `deduce_directory` 6 | 7 | ## Lexing and Parsing 8 | 9 | Deduce starts by building an AST 10 | 11 | - Uses lark to lex 12 | - Either recursive descent parser or lark parser 13 | - `Deduce.lark` is maintained for lexing and documentation of the grammar, as well as allowing for the use of lark's parser. 14 | 15 | See [`Abstract Syntax`](./abstract-syntax.md) for documentation of the various ast nodes. 16 | 17 | 18 | 19 | ## TODO: `check_deduce` 20 | 21 | The checking process for programs & proofs has three steps: 22 | 23 | 1. `process_declarations`: 24 | Collects the type environment for the top-level statements, usually 25 | from their declared types. (Except for define's without types.) 26 | 2. `type_check_stmt`: 27 | Type check the bodies of functions using the type environment. 28 | Perform overload resolution using the types. 29 | 3. `collect_env`: 30 | Collects the proofs (mapping proof labels to their formulas 31 | and runtime environment mapping variables to values) 32 | and the values (mapping names to their values, for defines a functions) 33 | into an environment. 34 | 4. `check_proofs`: 35 | Check that the proofs follow the rules of logic 36 | and run the print and assert statements. 37 | 38 | 39 | Explain bidirectional -------------------------------------------------------------------------------- /docs/knowledge-base/what-to-update.md: -------------------------------------------------------------------------------- 1 | # What to update 2 | 3 | Deduce has a lot of internal working parts as well as external tools that rely on being up to date with the latest release of Deduce. This page is here to list what updates need to be made when a new change is added to a specific part of Deduce. 4 | 5 | ## Syntax changes 6 | 7 | Any changes to the Deduce syntax should be reflected in the following places: 8 | 9 | 10 | **Internal:** 11 | - `Deduce.lark`: syntax rules for the lark parser 12 | - `parser.py`: code for the lark parser 13 | - `recursive-descent.py`: code for the recursive descent parser 14 | - `abstract_syntax.py`: code for all of the AST nodes 15 | - `gh_pages/doc/lib_generate.py`: generates the html files for the stdlib. (The list of known tokens mapping to token type should be updated). 16 | - `gh_pages/js/codeUtils.js`: syntax highlighting for the site codeblocks. 17 | - `gh_pages/js/sandbox.js`: syntax highlighting for live code monaco editor. 18 | 19 | **External:** 20 | - [deduce-mode (vscode)](https://github.com/HalflingHelper/deduce-mode#): Deduce extension for vscode. 21 | - [deduce-mode (emacs)](https://github.com/mateidragony/deduce-mode#): Deduce package for emacs. 22 | -------------------------------------------------------------------------------- /edit_distance.py: -------------------------------------------------------------------------------- 1 | from math import ceil 2 | 3 | space_penalty = 1 4 | space_char = '_' 5 | 6 | def score(x, y): 7 | if x == space_char or y == space_char: 8 | return space_penalty 9 | elif x == y: 10 | return 0 11 | else: 12 | return 1 13 | 14 | def edit_distance(s1, s2): 15 | m = len(s1); n = len(s2) 16 | F = {} 17 | F[(0, 0)] = 0 18 | for i in range(1, m+1): 19 | F[(i, 0)] = space_penalty * i 20 | 21 | for j in range(1, n+1): 22 | F[(0, j)] = space_penalty * j 23 | 24 | for i in range(1, m+1): 25 | for j in range(1, n+1): 26 | match = F[(i-1, j-1)] + score(s1[i-1], s2[j-1]) 27 | delete = F[(i-1, j)] + space_penalty 28 | insert = F[(i, j-1)] + space_penalty 29 | F[(i, j)] = min(match, delete, insert) 30 | return F[(m, n)] 31 | 32 | def closest_keyword(word, keywords): 33 | best_yet = None 34 | for kw in keywords: 35 | d = edit_distance(word, kw) 36 | if d <= ceil(len(word) / 6): 37 | if best_yet == None or d < best_yet[1]: 38 | best_yet = (kw, d) 39 | if best_yet: 40 | return best_yet[0] 41 | else: 42 | return None 43 | -------------------------------------------------------------------------------- /entangled.toml: -------------------------------------------------------------------------------- 1 | # required: the minimum version of Entangled 2 | version = "2.0" 3 | 4 | # default watch_list is ["**/*.md"] 5 | watch_list = ["**/*.md"] 6 | 7 | # default ignore_list is ["**/README.md"] 8 | ignore_list = [] 9 | 10 | [[languages]] 11 | name = "Deduce" 12 | identifiers = ["deduce"] 13 | comment = { open = "/*", close = "*/" } -------------------------------------------------------------------------------- /example.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import List 3 | 4 | define x = 1 5 | 6 | theorem one_x: 1 = x 7 | proof 8 | suffices 1 = 1 by definition x 9 | . 10 | end 11 | -------------------------------------------------------------------------------- /gh_pages/README.md: -------------------------------------------------------------------------------- 1 | # Deduce Website 2 | 3 | Website for the wonderful [deduce](https://github.com/jsiek/deduce "deduce source code") 4 | 5 | The content of the website is generated from the markdown files in the `doc` directory. 6 | For example, the `index.html` file is generated from `Index.md`. 7 | -------------------------------------------------------------------------------- /gh_pages/doc/StandardLib.md: -------------------------------------------------------------------------------- 1 | # Standard Library 2 | 3 | This section provides links to the theorems defined in the Deduce standard library along with the source files for the Deduce standard library. 4 | 5 | - ([`Base.thm`](../lib/Base.thm), [`Base.pf`](../lib/Base.pf)): Base proofs about propositional and predicate logic 6 | - ([`Int.thm`](../lib/Int.thm), [`Int.pf`](../lib/Int.pf)): Integers 7 | - ([`List.thm`](../lib/List.thm), [`List.pf`](../lib/List.pf)): Lists 8 | - ([`Log.thm`](../lib/Log.thm), [`Log.pf`](../lib/Log.pf)): Logarithms on natural numbers 9 | - ([`Maps.thm`](../lib/Maps.thm), [`Maps.pf`](../lib/Maps.pf)): Functional maps 10 | - ([`MultiSet.thm`](../lib/MultiSet.thm), [`MultiSet.pf`](../lib/MultiSet.pf)): Multisets 11 | - ([`Nat.thm`](../lib/Nat.thm), [`Nat.pf`](../lib/Nat.pf)): Natural numbers 12 | - ([`Option.pf`](../lib/Option.pf)): Optional values 13 | - ([`Pair.pf`](../lib/Pair.pf)): Pairs 14 | - ([`Set.thm`](../lib/Set.thm), [`Set.pf`](../lib/Set.pf)): Sets 15 | - ([`Sums.thm`](../lib/Sums.thm), [`Sums.pf`](../lib/Sums.pf)): Proofs of summation formulae 16 | -------------------------------------------------------------------------------- /gh_pages/doc/SyntaxGrammar.md: -------------------------------------------------------------------------------- 1 | # Syntax and Grammar Overview 2 | 3 | ## Phrases 4 | 5 | The Deduce language includes four kinds of phrases: 6 | 7 | 1. Statements 8 | 2. Proofs 9 | 3. Terms 10 | 4. Types 11 | 12 | ## Statements 13 | 14 | A deduce file contains a list of statements. Each statement can be one of: 15 | 16 | 1. [Theorem](./Reference.md#theorem-statement) 17 | 2. [Union](./Reference.md#union-statement) 18 | 3. [Function](./Reference.md#function-statement) 19 | 4. [Recursive Function](./Reference.md#recursive-function-statement) 20 | 5. [Define](./Reference.md#define-statement) 21 | 6. [Import](./Reference.md#import-statement) 22 | 7. [Assert](./Reference.md#assert-statement) 23 | 8. [Print](./Reference.md#print-statement) 24 | 25 | ## Proofs 26 | 27 | In Deduce, one must give a reason for why a theorem is true, and the reason is given by a proof. Proofs are constructed using the rules of logic together with ways to organize proofs by working backwards from the goal, or forwards from the assumptions. 28 | 29 | ## Terms 30 | 31 | Both logical formulas and program expressions are represented in Deduce by terms. For example, `if P then Q` is a logical formula and `x + 5` is a program expression, and to Deduce they are both terms. 32 | 33 | ## Types 34 | 35 | Each term has a type that classifies the kinds of values that are produced by the term. 36 | 37 | 1. The type `bool` classifies `true` or `false`. 38 | 2. The function type `fn T1,...,Tn -≥ Tr` classifies a function whose `n` parameters are of type `T1, ..., Tn` and whose return type is `Tr`. 39 | 3. The generic function type `fn T1,...,Tn -≥ Tr` classifies a generic function with type parameters `X1, ..., Xk`. 40 | 4. A union type given by its name. 41 | 5. An instance of a generic union is given by its name followed by `<`, a comma-separated list of type arguments, followed by `>`. 42 | 43 | ## Deduce Unicode 44 | 45 | Deduce uses some Unicode characters, but in case it is difficult for you to use Unicode, there are regular ASCI equivalents that you can use instead. 46 | 47 | | Unicode | ASCI | 48 | | ------- | ---- | 49 | | ≠ | /= | 50 | | ≤ | <= | 51 | | ≥ | >= | 52 | | ⊆ | (= | 53 | | ∈ | in | 54 | | ∪ | \| | 55 | | ∩ | & | 56 | | ⨄ | .+. | 57 | | ∘ | .o. | 58 | | ∅ | .0. | 59 | | λ | fun | 60 | 61 | -------------------------------------------------------------------------------- /gh_pages/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /gh_pages/requirements.txt: -------------------------------------------------------------------------------- 1 | markdown==3.7 2 | lark==1.2.2 3 | libsass==0.23.0 -------------------------------------------------------------------------------- /lib/Option.pf: -------------------------------------------------------------------------------- 1 | union Option { 2 | none 3 | just(T) 4 | } 5 | 6 | fun after(o : Option, f : fn (T) -> U) { 7 | switch o { 8 | case none { @none } 9 | case just(x) { just(f(x)) } 10 | } 11 | } 12 | 13 | fun default(o : Option, y : T) { 14 | switch o { 15 | case none { y } 16 | case just(x) { x } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/Pair.pf: -------------------------------------------------------------------------------- 1 | union Pair { 2 | pair(T,U) 3 | } 4 | 5 | fun first(p : Pair) { 6 | switch p { 7 | case pair(x,y) { x } 8 | } 9 | } 10 | 11 | fun second(p : Pair) { 12 | switch p { 13 | case pair(x,y) { y } 14 | } 15 | } 16 | 17 | fun pairfun(f : fn T1->T2, g : fn U1->U2) { 18 | fun p: Pair { 19 | pair(f(first(p)), g(second(p))) 20 | } 21 | } 22 | 23 | theorem first_pair: all T:type,U:type, x:T, y:U. first(pair(x,y)) = x 24 | proof 25 | arbitrary T:type,U:type, x:T, y:U 26 | expand first. 27 | end 28 | 29 | theorem second_pair: all T:type,U:type, x:T, y:U. second(pair(x,y)) = y 30 | proof 31 | arbitrary T:type,U:type, x:T, y:U 32 | expand second. 33 | end 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /live_code_vercel_api/api.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, jsonify, request, Response 2 | from contextlib import redirect_stdout, redirect_stderr 3 | from pathlib import Path 4 | import subprocess 5 | import os 6 | import uuid 7 | import sys 8 | import io 9 | 10 | from proof_checker import check_deduce, uniquify_deduce 11 | from abstract_syntax import get_uniquified_modules, add_uniquified_module, add_import_directory 12 | import rec_desc_parser 13 | 14 | app = Flask(__name__) 15 | PORT = 12357 16 | 17 | def deduce_file(filename, error_expected): 18 | module_name = Path(filename).stem 19 | 20 | try: 21 | if module_name in get_uniquified_modules().keys(): 22 | ast = get_uniquified_modules()[module_name] 23 | else: 24 | file = open(filename, 'r', encoding="utf-8") 25 | program_text = file.read() 26 | rec_desc_parser.set_filename(filename) 27 | 28 | ast = rec_desc_parser.parse(program_text, False, False) 29 | uniquify_deduce(ast) 30 | add_uniquified_module(module_name, ast) 31 | 32 | check_deduce(ast, module_name) 33 | print(filename + ' is valid') 34 | 35 | except Exception as e: 36 | print(str(e)) 37 | 38 | 39 | 40 | @app.route('/deduce', methods=['POST']) 41 | def deduce_req(): 42 | # Get user code 43 | deduce_code = request.data.decode("utf-8") 44 | print("Code received: " + deduce_code) 45 | 46 | # Generate a unique filename for the user code 47 | unique_id = str(uuid.uuid4()) 48 | code_filename = f"/tmp/{unique_id}.pf" 49 | with open(code_filename, "w") as code_file: 50 | code_file.write(deduce_code) 51 | 52 | # Start deducing 53 | rec_desc_parser.set_deduce_directory("./") 54 | rec_desc_parser.init_parser() 55 | add_import_directory("./lib") 56 | 57 | try: 58 | with redirect_stdout(io.StringIO()) as stdout: 59 | deduce_file(f"/tmp/{unique_id}.pf", False) 60 | deduce_output = stdout.getvalue() 61 | except Exception as e: 62 | deduce_output = str(e) 63 | 64 | deduce_output = deduce_output.replace(f"/tmp/{unique_id}", "input") 65 | print(f"Output: {deduce_output}") 66 | 67 | # Cleanup temporary files 68 | pf_file = f"/tmp/{unique_id}.pf" 69 | thm_file = f"/tmp/{unique_id}.thm" 70 | if os.path.isfile(pf_file) : os.remove(pf_file) 71 | if os.path.isfile(thm_file): os.remove(thm_file) 72 | 73 | # Return the output 74 | res = Response(deduce_output) 75 | res.headers["Access-Control-Allow-Origin"] = "*" 76 | return res 77 | 78 | 79 | if __name__ == '__main__': 80 | app.run(port=12347) 81 | -------------------------------------------------------------------------------- /live_code_vercel_api/image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsiek/deduce/e9bdafe9a6ff48206d15f0bde9152cc9e516558e/live_code_vercel_api/image-1.png -------------------------------------------------------------------------------- /live_code_vercel_api/image-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsiek/deduce/e9bdafe9a6ff48206d15f0bde9152cc9e516558e/live_code_vercel_api/image-2.png -------------------------------------------------------------------------------- /live_code_vercel_api/image-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsiek/deduce/e9bdafe9a6ff48206d15f0bde9152cc9e516558e/live_code_vercel_api/image-3.png -------------------------------------------------------------------------------- /live_code_vercel_api/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsiek/deduce/e9bdafe9a6ff48206d15f0bde9152cc9e516558e/live_code_vercel_api/image.png -------------------------------------------------------------------------------- /live_code_vercel_api/requirements.txt: -------------------------------------------------------------------------------- 1 | flask==2.3.3 2 | lark==1.2.2 -------------------------------------------------------------------------------- /logos/Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | lark==1.2.2 2 | -------------------------------------------------------------------------------- /test/parse/all_dot.pf: -------------------------------------------------------------------------------- 1 | // Same as all5.pf 2 | 3 | theorem T: all x : bool x = x 4 | proof 5 | arbitrary x:bool 6 | conclude x = x by . 7 | end -------------------------------------------------------------------------------- /test/parse/all_dot.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/all_dot.pf:3.1-3.24: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/all_dot.pf:3.25-3.26: expected "." after parameters of "all", not 4 | x 5 | while parsing 6 | term ::= "all" var_list "." term 7 | -------------------------------------------------------------------------------- /test/parse/apply.pf: -------------------------------------------------------------------------------- 1 | theorem demo : all b : bool, c : bool. 2 | if b = true then b or c 3 | proof 4 | arbitrary b : bool, c : bool 5 | assume prem 6 | rewrite prem 7 | end 8 | 9 | theorem use_demo : all b : bool, c : bool. 10 | if b then b or c 11 | proof 12 | arbitrary b : bool, c : bool 13 | suppose prem 14 | have b_t : b = true 15 | by switch b { 16 | case true assume prop_t { 17 | prop_t 18 | } 19 | case false assume prop_f { 20 | rewrite prop_f in prem 21 | } 22 | } 23 | apply demo[b, c] b_t 24 | end -------------------------------------------------------------------------------- /test/parse/apply.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/apply.pf:1.1-6.10: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/apply.pf:6.11-6.15: expected the keyword "end" after proof of theorem, not 4 | prem 5 | -------------------------------------------------------------------------------- /test/parse/array1.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | union List { 7 | empty 8 | node(T, List) 9 | } 10 | 11 | define L = [true, false, true] 12 | define A = array(L) 13 | assert A[0 = true 14 | assert A[1] = false 15 | assert A[2] = true -------------------------------------------------------------------------------- /test/parse/array1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/array1.pf:13.1-13.18: while parsing assert 2 | statement ::= "assert" formula 3 | 4 | ./test/parse/array1.pf:13.9-13.18: while parsing array access 5 | term ::= term "[" term "]" 6 | 7 | ./test/parse/array1.pf:13.9-14.7: expected closing "]", not 8 | assert 9 | -------------------------------------------------------------------------------- /test/parse/array2.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | union List { 7 | empty 8 | node(T, List) 9 | } 10 | 11 | define L = [true, false, true] 12 | define A = array L 13 | 14 | assert A[2] = true -------------------------------------------------------------------------------- /test/parse/array2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/array2.pf:12.1-12.17: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/array2.pf:12.1-12.17: while parsing 4 | proof_stmt ::= "define" identifier "=" term 5 | 6 | ./test/parse/array2.pf:12.12-12.17: while parsing array creation 7 | term ::= "array" "(" term ")" 8 | 9 | ./test/parse/array2.pf:12.12-12.19: expected open parenthesis "(", not 10 | L 11 | -------------------------------------------------------------------------------- /test/parse/array3.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | union List { 7 | empty 8 | node(T, List) 9 | } 10 | 11 | define L = [true, false, true] 12 | define A = array(L 13 | 14 | assert A[2] = true -------------------------------------------------------------------------------- /test/parse/array3.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/array3.pf:12.1-12.19: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/array3.pf:12.1-12.19: while parsing 4 | proof_stmt ::= "define" identifier "=" term 5 | 6 | ./test/parse/array3.pf:12.12-12.19: while parsing array creation 7 | term ::= "array" "(" term ")" 8 | 9 | ./test/parse/array3.pf:12.12-14.7: expected closing parenthesis ")", not 10 | assert 11 | -------------------------------------------------------------------------------- /test/parse/call1.pf: -------------------------------------------------------------------------------- 1 | define f : fn bool -> bool 2 | = fun b { not b } 3 | 4 | print f(true 5 | print f(false) -------------------------------------------------------------------------------- /test/parse/call1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/call1.pf:4.1-4.13: while parsing 2 | statement ::= "print" term 3 | 4 | ./test/parse/call1.pf:4.7-4.13: while parsing function call 5 | term ::= term "(" term_list ")" 6 | 7 | ./test/parse/call1.pf:4.7-4.13: expected closing parenthesis ")", not 8 | print 9 | Perhaps you forgot a comma? 10 | -------------------------------------------------------------------------------- /test/parse/call2_comma.pf: -------------------------------------------------------------------------------- 1 | define f : fn bool, bool -> bool 2 | = fun b, c { not b } 3 | 4 | define c = true 5 | 6 | print f(true false) 7 | print f(false, true) -------------------------------------------------------------------------------- /test/parse/call2_comma.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/call2_comma.pf:6.1-6.13: while parsing 2 | statement ::= "print" term 3 | 4 | ./test/parse/call2_comma.pf:6.7-6.13: while parsing function call 5 | term ::= term "(" term_list ")" 6 | 7 | ./test/parse/call2_comma.pf:6.7-6.13: expected closing parenthesis ")", not 8 | false 9 | Perhaps you forgot a comma? 10 | -------------------------------------------------------------------------------- /test/parse/cases1.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all x : bool. true 2 | proof 3 | arbitrary x : bool 4 | have q : false or true by . 5 | cases q 6 | case a . } 7 | case b : false { . } 8 | end 9 | -------------------------------------------------------------------------------- /test/parse/cases1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/cases1.pf:5.3-6.9: while parsing cases (use a logical or) 2 | conclusion ::= "cases" proof case_clause* 3 | case_clause ::= "case" identifier ":" term "{" proof "}" 4 | 5 | ./test/parse/cases1.pf:6.3-6.14: while parsing: 6 | "case" label ":" formula "{" proof "}" 7 | ./test/parse/cases1.pf:6.3-6.14: expected a "{" after assumption of "case", not 8 | . 9 | -------------------------------------------------------------------------------- /test/parse/cases2.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all x : bool. true 2 | proof 3 | arbitrary x : bool 4 | have q : false or true by . 5 | cases q 6 | case a { . 7 | case b : false { . } 8 | end 9 | -------------------------------------------------------------------------------- /test/parse/cases2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/cases2.pf:1.1-6.16: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/cases2.pf:5.3-6.16: while parsing cases (use a logical or) 4 | conclusion ::= "cases" proof case_clause* 5 | case_clause ::= "case" identifier ":" term "{" proof "}" 6 | 7 | ./test/parse/cases2.pf:6.3-7.7: expected a "}" after body of "case", not 8 | case 9 | -------------------------------------------------------------------------------- /test/parse/conclude.pf: -------------------------------------------------------------------------------- 1 | define const_t1 : fn E -> bool = generic E { fun x { true } } 2 | define const_t2 : fn E -> bool = generic E { fun x { true } } 3 | 4 | theorem blah : all T : type, x : T. const_t1(const_t2(x)) = true 5 | proof 6 | conclude all T : type, x : T. const_t1(const_t2(x)) = true 7 | definition { const_t2, const_t1 } 8 | end 9 | -------------------------------------------------------------------------------- /test/parse/conclude.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/conclude.pf:4.1-6.61: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/conclude.pf:6.3-6.61: while parsing 4 | conclusion ::= "conclude" formula "by" proof 5 | 6 | ./test/parse/conclude.pf:7.5-7.15: expected the keyword "by" after formula of "conclude", not 7 | definition 8 | -------------------------------------------------------------------------------- /test/parse/conjunct1.pf: -------------------------------------------------------------------------------- 1 | theorem demo : all b : bool, c : bool. 2 | if b and c then b 3 | proof 4 | arbitrary b : bool, c : bool 5 | suppose prem 6 | conjunct not_number of prem 7 | end -------------------------------------------------------------------------------- /test/parse/conjunct1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/conjunct1.pf:1.1-6.11: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/conjunct1.pf:6.12-6.22: expected an int literal after "conjunct", not 4 | not_number 5 | -------------------------------------------------------------------------------- /test/parse/conjunct2.pf: -------------------------------------------------------------------------------- 1 | theorem demo : all b : bool, c : bool. 2 | if b and c then b 3 | proof 4 | arbitrary b : bool, c : bool 5 | suppose prem 6 | conjunct 0 prem 7 | end -------------------------------------------------------------------------------- /test/parse/conjunct2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/conjunct2.pf:1.1-6.13: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/conjunct2.pf:6.15-6.19: expected keyword "of" after index of "conjunct", not 4 | prem 5 | -------------------------------------------------------------------------------- /test/parse/define_1.pf: -------------------------------------------------------------------------------- 1 | define a 3 -------------------------------------------------------------------------------- /test/parse/define_1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/define_1.pf:1.1-1.9: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/define_1.pf:1.1-1.9: while parsing 4 | proof_stmt ::= "define" identifier "=" term 5 | 6 | ./test/parse/define_1.pf:1.10-1.11: expected "=" after name in "define" 7 | -------------------------------------------------------------------------------- /test/parse/define_term1.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all a : bool, c : bool. 2 | define H a and c; 3 | H or not a or not c 4 | proof 5 | arbitrary a : bool, c : bool 6 | define H = a and c 7 | ? 8 | end -------------------------------------------------------------------------------- /test/parse/define_term1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/define_term1.pf:1.1-2.11: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/define_term1.pf:2.3-2.11: while parsing 4 | term ::= "define" identifier "=" term ";" term 5 | 6 | ./test/parse/define_term1.pf:2.13-2.14: expected "=" after name in "define", not 7 | "a" 8 | -------------------------------------------------------------------------------- /test/parse/define_term2.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all a : bool, c : bool. 2 | define H = a and c 3 | H or not a or not c 4 | proof 5 | arbitrary a : bool, c : bool 6 | define H = a and c 7 | ? 8 | end -------------------------------------------------------------------------------- /test/parse/define_term2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/define_term2.pf:1.1-2.21: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/define_term2.pf:2.3-2.21: while parsing 4 | term ::= "define" identifier "=" term ";" term 5 | 6 | ./test/parse/define_term2.pf:3.3-3.4: expected ";" after right-hand side of "define", not 7 | "H" 8 | -------------------------------------------------------------------------------- /test/parse/eof_def.pf: -------------------------------------------------------------------------------- 1 | define -------------------------------------------------------------------------------- /test/parse/eof_def.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/eof_def.pf:1.1-1.7: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/eof_def.pf:1.1-1.7: while parsing 4 | proof_stmt ::= "define" identifier "=" term 5 | 6 | ./test/parse/eof_def.pf:1.1-1.7: expected an identifier, not end of file 7 | -------------------------------------------------------------------------------- /test/parse/eof_def_1.pf: -------------------------------------------------------------------------------- 1 | define a -------------------------------------------------------------------------------- /test/parse/eof_def_1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/eof_def_1.pf:1.1-1.9: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/eof_def_1.pf:1.1-1.9: while parsing 4 | proof_stmt ::= "define" identifier "=" term 5 | 6 | ./test/parse/eof_def_1.pf:1.8-1.9: Expected a token, got end of file 7 | -------------------------------------------------------------------------------- /test/parse/eof_have_0.pf: -------------------------------------------------------------------------------- 1 | theorem blah : true 2 | proof 3 | have -------------------------------------------------------------------------------- /test/parse/eof_have_0.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/eof_have_0.pf:1.1-3.7: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/eof_have_0.pf:3.3-3.7: while parsing 4 | proof_stmt ::= "have" identifier ":" formula "by" proof 5 | proof_stmt ::= "have" ":" formula "by" proof 6 | 7 | ./test/parse/eof_have_0.pf:3.3-3.7: expected an identifier or colon after "have", not end of file 8 | -------------------------------------------------------------------------------- /test/parse/eof_have_1.pf: -------------------------------------------------------------------------------- 1 | theorem blah : true 2 | proof 3 | have : -------------------------------------------------------------------------------- /test/parse/eof_have_1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/eof_have_1.pf:1.1-3.9: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/eof_have_1.pf:3.3-3.9: while parsing 4 | proof_stmt ::= "have" identifier ":" formula "by" proof 5 | proof_stmt ::= "have" ":" formula "by" proof 6 | 7 | ./test/parse/eof_have_1.pf:3.8-3.9: expected a term, not end of file 8 | -------------------------------------------------------------------------------- /test/parse/eof_have_2.pf: -------------------------------------------------------------------------------- 1 | theorem blah : true 2 | proof 3 | have asdf -------------------------------------------------------------------------------- /test/parse/eof_have_2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/eof_have_2.pf:1.1-3.12: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/eof_have_2.pf:3.3-3.12: while parsing 4 | proof_stmt ::= "have" identifier ":" formula "by" proof 5 | proof_stmt ::= "have" ":" formula "by" proof 6 | 7 | ./test/parse/eof_have_2.pf:3.3-3.7: expected a colon after label of "have", not end of file 8 | -------------------------------------------------------------------------------- /test/parse/eof_have_3.pf: -------------------------------------------------------------------------------- 1 | theorem blah : true 2 | proof 3 | have asdf : true -------------------------------------------------------------------------------- /test/parse/eof_have_3.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/eof_have_3.pf:1.1-3.19: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/eof_have_3.pf:3.3-3.19: while parsing 4 | proof_stmt ::= "have" identifier ":" formula "by" proof 5 | proof_stmt ::= "have" ":" formula "by" proof 6 | 7 | ./test/parse/eof_have_3.pf:3.3-3.7: expected the keyword "by" after formula of "have", not end of file 8 | -------------------------------------------------------------------------------- /test/parse/eof_proof.pf: -------------------------------------------------------------------------------- 1 | theorem blah : true 2 | proof -------------------------------------------------------------------------------- /test/parse/eof_proof.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/eof_proof.pf:1.1-2.6: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/eof_proof.pf:2.1-2.6: expected a proof, not end of file 4 | -------------------------------------------------------------------------------- /test/parse/eof_term.pf: -------------------------------------------------------------------------------- 1 | define a = -------------------------------------------------------------------------------- /test/parse/eof_term.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/eof_term.pf:1.1-1.11: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/eof_term.pf:1.1-1.11: while parsing 4 | proof_stmt ::= "define" identifier "=" term 5 | 6 | ./test/parse/eof_term.pf:1.10-1.11: expected a term, not end of file 7 | -------------------------------------------------------------------------------- /test/parse/fun_1.pf: -------------------------------------------------------------------------------- 1 | define blah : fn bool -> bool 2 | = fun x x -------------------------------------------------------------------------------- /test/parse/fun_1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/fun_1.pf:1.1-2.9: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/fun_1.pf:1.1-2.9: while parsing 4 | proof_stmt ::= "define" identifier ":" type "=" term 5 | 6 | ./test/parse/fun_1.pf:2.4-2.11: expected "{" after parameters of fun, not 7 | x 8 | -------------------------------------------------------------------------------- /test/parse/fun_2.pf: -------------------------------------------------------------------------------- 1 | define blah : fn bool -> bool 2 | = fun x { x 3 | 4 | assert true -------------------------------------------------------------------------------- /test/parse/fun_2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/fun_2.pf:1.1-2.13: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/fun_2.pf:1.1-2.13: while parsing 4 | proof_stmt ::= "define" identifier ":" type "=" term 5 | 6 | ./test/parse/fun_2.pf:2.4-2.13: expected "}" after body of "fun", not 7 | assert 8 | -------------------------------------------------------------------------------- /test/parse/generic_1.pf: -------------------------------------------------------------------------------- 1 | define a : fn E, E, bool -> E 2 | = generic E fun x, y, p { if p then x else y } -------------------------------------------------------------------------------- /test/parse/generic_1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/generic_1.pf:1.1-2.14: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/generic_1.pf:1.1-2.14: while parsing 4 | proof_stmt ::= "define" identifier ":" type "=" term 5 | 6 | ./test/parse/generic_1.pf:2.5-2.19: expected "{" after parameters of "generic", not 7 | fun 8 | -------------------------------------------------------------------------------- /test/parse/generic_2.pf: -------------------------------------------------------------------------------- 1 | define a : fn E, E, bool -> E 2 | = generic E { fun x, y, p { if p then x else y } 3 | 4 | print true -------------------------------------------------------------------------------- /test/parse/generic_2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/generic_2.pf:1.1-2.51: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/generic_2.pf:1.1-2.51: while parsing 4 | proof_stmt ::= "define" identifier ":" type "=" term 5 | 6 | ./test/parse/generic_2.pf:2.5-4.6: expected "}" after body of "generic", not 7 | print 8 | -------------------------------------------------------------------------------- /test/parse/hash_term.pf: -------------------------------------------------------------------------------- 1 | print # true 2 | print false 3 | 4 | -------------------------------------------------------------------------------- /test/parse/hash_term.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/hash_term.pf:1.1-1.13: while parsing 2 | statement ::= "print" term 3 | 4 | ./test/parse/hash_term.pf:2.1-2.6: expected closing hash "#", not 5 | print 6 | -------------------------------------------------------------------------------- /test/parse/have_no_by.pf: -------------------------------------------------------------------------------- 1 | theorem idk : true 2 | proof 3 | have t : true . 4 | . 5 | end -------------------------------------------------------------------------------- /test/parse/have_no_by.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/have_no_by.pf:1.1-3.16: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/have_no_by.pf:3.3-3.16: while parsing 4 | proof_stmt ::= "have" identifier ":" formula "by" proof 5 | proof_stmt ::= "have" ":" formula "by" proof 6 | 7 | ./test/parse/have_no_by.pf:3.17-3.18: expected the keyword "by" after formula of "have", not 8 | . 9 | -------------------------------------------------------------------------------- /test/parse/have_no_colon.pf: -------------------------------------------------------------------------------- 1 | theorem idk : true 2 | proof 3 | have t true by . 4 | t 5 | end -------------------------------------------------------------------------------- /test/parse/have_no_colon.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/have_no_colon.pf:1.1-3.9: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/have_no_colon.pf:3.3-3.9: while parsing 4 | proof_stmt ::= "have" identifier ":" formula "by" proof 5 | proof_stmt ::= "have" ":" formula "by" proof 6 | 7 | ./test/parse/have_no_colon.pf:3.11-3.15: expected a colon after label of "have", not 8 | true 9 | -------------------------------------------------------------------------------- /test/parse/id_eof_thm.pf: -------------------------------------------------------------------------------- 1 | theorem -------------------------------------------------------------------------------- /test/parse/id_eof_thm.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/id_eof_thm.pf:1.1-1.8: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/id_eof_thm.pf:1.1-1.8: expected name of theorem, not end of file 4 | -------------------------------------------------------------------------------- /test/parse/id_miss.pf: -------------------------------------------------------------------------------- 1 | theorem 42 -------------------------------------------------------------------------------- /test/parse/id_miss.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/id_miss.pf:1.1-1.8: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/id_miss.pf:1.9-1.11: expected name of theorem, not: 4 | 42 5 | -------------------------------------------------------------------------------- /test/parse/if_no_then.pf: -------------------------------------------------------------------------------- 1 | define a : fn bool -> bool 2 | = fun x { 3 | if x false else true 4 | } 5 | 6 | print a(true) 7 | print a(false) 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/parse/if_no_then.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/if_no_then.pf:1.1-3.9: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/if_no_then.pf:1.1-3.9: while parsing 4 | proof_stmt ::= "define" identifier ":" type "=" term 5 | 6 | ./test/parse/if_no_then.pf:3.11-3.16: expected keyword "then" after premise of "if" formula, not 7 | false 8 | while parsing 9 | formula ::= "if" formula "then" formula 10 | -------------------------------------------------------------------------------- /test/parse/inst-term-angle-bracket.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | 4 | theorem thm: if ( all xs:List. map(xs, fun x:T { x }) = xs) 5 | then map(node(1, empty), fun x:Nat { x }) = node(1, empty) 6 | proof 7 | suppose prem: ( all xs:List. map(xs, fun x:T { x }) = xs) 8 | prem 9 | end 10 | -------------------------------------------------------------------------------- /test/parse/inst-term-angle-bracket.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/inst-term-angle-bracket.pf:4.1-8.17: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/inst-term-angle-bracket.pf:8.3-8.18: while trying to parse type arguments for instantiation of an "all" formula: 4 | proof ::= proof "<" type_list ">" 5 | ./test/parse/inst-term-angle-bracket.pf:8.3-8.18: expected a closing ">", not 6 | "(" 7 | -------------------------------------------------------------------------------- /test/parse/instant1.pf: -------------------------------------------------------------------------------- 1 | union List { 2 | empty 3 | node(T, List) 4 | } 5 | 6 | union A { a } 7 | 8 | 9 | assert @[] = (@[]) 10 | -------------------------------------------------------------------------------- /test/parse/instant1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/instant1.pf:9.1-9.21: while parsing assert 2 | statement ::= "assert" formula 3 | 4 | ./test/parse/instant1.pf:9.21-9.22: expected "<" after subject of instantiation ("@"), not 5 | ) 6 | while parsing 7 | term ::= "@" term "<" type_list ">" 8 | -------------------------------------------------------------------------------- /test/parse/instant2.pf: -------------------------------------------------------------------------------- 1 | union List { 2 | empty 3 | node(T, List) 4 | } 5 | 6 | union A { a } 7 | 8 | 9 | assert @[] = (@" after type parameters 5 | -------------------------------------------------------------------------------- /test/parse/list1.pf: -------------------------------------------------------------------------------- 1 | union List { 2 | empty 3 | node(T, List) 4 | } 5 | 6 | print [true, false 7 | 8 | print [false] -------------------------------------------------------------------------------- /test/parse/list1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/list1.pf:6.1-6.19: while parsing 2 | statement ::= "print" term 3 | 4 | ./test/parse/list1.pf:8.1-8.6: expected closing bracket "]" at end of list literal, not 5 | print 6 | -------------------------------------------------------------------------------- /test/parse/misspell.pf: -------------------------------------------------------------------------------- 1 | // Stolen from suffices misspell.pf 2 | 3 | theorem T: all P:bool, Q:bool, R:bool. if (if P then Q) and (if Q then R) and P then R 4 | proof 5 | arbitrary P:bool, Q:bool, R:bool 6 | suppose prem 7 | sufices Q by prem 8 | suffices P by prem 9 | prem 10 | end 11 | -------------------------------------------------------------------------------- /test/parse/misspell.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/misspell.pf:3.1-6.15: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/misspell.pf:7.3-7.10: expected a proof. 4 | Did you mean "suffices" instead of "sufices"? 5 | -------------------------------------------------------------------------------- /test/parse/no_term.pf: -------------------------------------------------------------------------------- 1 | // Same as define_proof_missing_term.pf 2 | 3 | theorem T: true 4 | proof 5 | define x = 6 | . 7 | end 8 | -------------------------------------------------------------------------------- /test/parse/no_term.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/no_term.pf:3.1-5.13: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/no_term.pf:5.3-5.13: while parsing 4 | proof_stmt ::= "define" identifier "=" term 5 | 6 | ./test/parse/no_term.pf:6.3-6.4: expected a term, not 7 | "." 8 | -------------------------------------------------------------------------------- /test/parse/paren_term.pf: -------------------------------------------------------------------------------- 1 | print (true 2 | 3 | print false -------------------------------------------------------------------------------- /test/parse/paren_term.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/paren_term.pf:1.1-1.12: while parsing 2 | statement ::= "print" term 3 | 4 | ./test/parse/paren_term.pf:3.1-3.6: expected closing parenthesis ")", not 5 | print 6 | while parsing parenthesized term 7 | term ::= "(" term ")" 8 | 9 | -------------------------------------------------------------------------------- /test/parse/pf_brace.pf: -------------------------------------------------------------------------------- 1 | theorem demo : all b : bool, c : bool. 2 | if b = true then b or c 3 | proof 4 | arbitrary b : bool, c : bool 5 | assume prem 6 | rewrite prem 7 | end 8 | 9 | theorem use_demo : all b : bool, c : bool. 10 | if b then b or c 11 | proof 12 | arbitrary b : bool, c : bool 13 | suppose prem 14 | have b_t : b = true 15 | by {switch b { 16 | case true assume prop_t { 17 | prop_t 18 | } 19 | case false assume prop_f { 20 | rewrite prop_f in prem 21 | } 22 | } 23 | apply demo[b, c] to b_t 24 | end -------------------------------------------------------------------------------- /test/parse/pf_brace.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/pf_brace.pf:1.1-6.10: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/pf_brace.pf:6.11-6.15: expected the keyword "end" after proof of theorem, not 4 | prem 5 | -------------------------------------------------------------------------------- /test/parse/pf_paren.pf: -------------------------------------------------------------------------------- 1 | theorem demo : all b : bool, c : bool. 2 | if b = true then b or c 3 | proof 4 | arbitrary b : bool, c : bool 5 | assume prem 6 | rewrite prem 7 | end 8 | 9 | theorem use_demo : all b : bool, c : bool. 10 | if b then b or c 11 | proof 12 | arbitrary b : bool, c : bool 13 | suppose prem 14 | have b_t : b = true 15 | by (switch b { 16 | case true assume prop_t { 17 | prop_t 18 | } 19 | case false assume prop_f { 20 | rewrite prop_f in prem 21 | } 22 | } 23 | apply demo[b, c] to b_t 24 | end -------------------------------------------------------------------------------- /test/parse/pf_paren.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/pf_paren.pf:1.1-6.10: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/pf_paren.pf:6.11-6.15: expected the keyword "end" after proof of theorem, not 4 | prem 5 | -------------------------------------------------------------------------------- /test/parse/plus_int.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | recursive operator +(Nat,Nat) -> Nat { 7 | operator +(0, m) = m 8 | operator +(suc(n), m) = suc(n + m) 9 | } 10 | 11 | define a : Nat = 4 12 | 13 | print + a 14 | -------------------------------------------------------------------------------- /test/parse/plus_int.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/plus_int.pf:13.1-13.8: while parsing 2 | statement ::= "print" term 3 | 4 | ./test/parse/plus_int.pf:13.9-13.10: expected an integer not 5 | a 6 | -------------------------------------------------------------------------------- /test/parse/proof_args_comma.pf: -------------------------------------------------------------------------------- 1 | theorem P : all x : bool, y : bool. 2 | true 3 | proof 4 | arbitrary x : bool, y : bool 5 | . 6 | end 7 | 8 | theorem Q : all w : bool, z : bool. 9 | true 10 | proof 11 | arbitrary w : bool, z : bool 12 | P[w z] 13 | end -------------------------------------------------------------------------------- /test/parse/proof_args_comma.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/proof_args_comma.pf:8.1-12.6: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/proof_args_comma.pf:12.7-12.8: expected a closing "]", not 4 | z 5 | Perhaps you forgot a comma? 6 | -------------------------------------------------------------------------------- /test/parse/proof_brace.pf: -------------------------------------------------------------------------------- 1 | theorem blah : true 2 | proof 3 | {. 4 | end -------------------------------------------------------------------------------- /test/parse/proof_brace.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/proof_brace.pf:1.1-3.5: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/proof_brace.pf:4.1-4.4: expected a closing "}" around proof, not 4 | end 5 | -------------------------------------------------------------------------------- /test/parse/proof_define.pf: -------------------------------------------------------------------------------- 1 | theorem blah : true 2 | proof 3 | define t true 4 | 5 | expand t 6 | 7 | . 8 | end -------------------------------------------------------------------------------- /test/parse/proof_define.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/proof_define.pf:1.1-3.11: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/proof_define.pf:3.3-3.11: while parsing 4 | proof_stmt ::= "define" identifier "=" term 5 | 6 | ./test/parse/proof_define.pf:3.12-3.16: expected "=" after name in "define", not 7 | true 8 | -------------------------------------------------------------------------------- /test/parse/proof_paren.pf: -------------------------------------------------------------------------------- 1 | theorem blah : true 2 | proof 3 | (. 4 | end -------------------------------------------------------------------------------- /test/parse/proof_paren.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/proof_paren.pf:1.1-3.5: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/proof_paren.pf:4.1-4.4: expected closing parenthesis ")" around proof, not 4 | end 5 | -------------------------------------------------------------------------------- /test/parse/some_dot.pf: -------------------------------------------------------------------------------- 1 | theorem T: some x : bool x = x 2 | proof 3 | choose false 4 | . 5 | end -------------------------------------------------------------------------------- /test/parse/some_dot.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/some_dot.pf:1.1-1.25: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/some_dot.pf:1.12-1.27: expected "." after parameters of "some", not 4 | x 5 | -------------------------------------------------------------------------------- /test/parse/suffices1.pf: -------------------------------------------------------------------------------- 1 | theorem blah : true 2 | proof 3 | suffices true . 4 | . 5 | end -------------------------------------------------------------------------------- /test/parse/suffices1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/suffices1.pf:1.1-3.16: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/suffices1.pf:3.18-3.19: expected the keyword "by" after formula of "suffices", not 4 | . 5 | -------------------------------------------------------------------------------- /test/parse/switch1.pf: -------------------------------------------------------------------------------- 1 | union Grade { 2 | A 3 | B 4 | C 5 | } 6 | 7 | 8 | define is_good : fn Grade -> bool 9 | = fun g { 10 | switch g 11 | case A { true } 12 | case B { true } 13 | case C { false } 14 | 15 | } -------------------------------------------------------------------------------- /test/parse/switch1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/switch1.pf:8.1-10.13: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/switch1.pf:8.1-10.13: while parsing 4 | proof_stmt ::= "define" identifier ":" type "=" term 5 | 6 | ./test/parse/switch1.pf:11.7-11.11: expected "{" after subject of "switch", not 7 | case 8 | -------------------------------------------------------------------------------- /test/parse/switch2.pf: -------------------------------------------------------------------------------- 1 | union Grade { 2 | A 3 | B 4 | C 5 | } 6 | 7 | 8 | define is_good : fn Grade -> bool 9 | = fun g { 10 | switch g { 11 | case A { true } 12 | case B { true } 13 | case C { false } 14 | ] 15 | } -------------------------------------------------------------------------------- /test/parse/switch2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/switch2.pf:8.1-13.23: while parsing 2 | declaration ::= union | rec_function | function | definition 3 | ./test/parse/switch2.pf:8.1-13.23: while parsing 4 | proof_stmt ::= "define" identifier ":" type "=" term 5 | 6 | ./test/parse/switch2.pf:10.5-14.6: expected "}" after last case of "switch", not 7 | ] 8 | -------------------------------------------------------------------------------- /test/parse/switch_pf1.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all x : bool. true 2 | proof 3 | arbitrary x : bool 4 | switch x 5 | case true assume prop_t { . } 6 | case false assume prop_f { . } 7 | 8 | end 9 | -------------------------------------------------------------------------------- /test/parse/switch_pf1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/switch_pf1.pf:1.1-4.11: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/switch_pf1.pf:5.5-5.9: expected "{" after subject of "switch", not 4 | case 5 | -------------------------------------------------------------------------------- /test/parse/switch_pf2.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all x : bool. true 2 | proof 3 | arbitrary x : bool 4 | switch x { 5 | case true assume prop_t { . } 6 | case false assume prop_f { . } 7 | 8 | end 9 | -------------------------------------------------------------------------------- /test/parse/switch_pf2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/switch_pf2.pf:1.1-6.35: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/switch_pf2.pf:4.3-8.4: expected "}" after last case of "switch", not 4 | end 5 | -------------------------------------------------------------------------------- /test/parse/switch_pf3.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all x : bool. true 2 | proof 3 | arbitrary x : bool 4 | switch x { 5 | case true . } 6 | case false assume prop_f { . } 7 | } 8 | end 9 | -------------------------------------------------------------------------------- /test/parse/switch_pf3.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/switch_pf3.pf:1.1-5.14: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/switch_pf3.pf:5.5-5.17: while parsing one of the following 4 | switch_proof_case ::= "case" pattern "{" proof "}" 5 | switch_proof_case ::= "case" pattern "assume" assumption_list "{" proof "}" 6 | ./test/parse/switch_pf3.pf:5.5-5.17: expected a "{" after assumption of "case", not 7 | . 8 | -------------------------------------------------------------------------------- /test/parse/switch_pf4.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all x : bool. true 2 | proof 3 | arbitrary x : bool 4 | switch x { 5 | case true { . 6 | case false assume prop_f { . } 7 | } 8 | end 9 | -------------------------------------------------------------------------------- /test/parse/switch_pf4.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/switch_pf4.pf:1.1-5.18: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/switch_pf4.pf:5.5-6.9: expected a "}" after body of case, not 4 | case 5 | -------------------------------------------------------------------------------- /test/parse/switch_pf5.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all x : bool. true 2 | proof 3 | arbitrary x : bool 4 | switch x { 5 | case true assume prop_t . } 6 | case false assume prop_f { . } 7 | } 8 | end 9 | -------------------------------------------------------------------------------- /test/parse/switch_pf5.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/switch_pf5.pf:1.1-5.28: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/switch_pf5.pf:5.5-5.31: while parsing one of the following 4 | switch_proof_case ::= "case" pattern "{" proof "}" 5 | switch_proof_case ::= "case" pattern "assume" assumption_list "{" proof "}" 6 | ./test/parse/switch_pf5.pf:5.5-5.31: expected a "{" after assumption of "case", not 7 | . 8 | -------------------------------------------------------------------------------- /test/parse/ty_params_1.pf: -------------------------------------------------------------------------------- 1 | union List { 2 | empty 3 | node(T, List) 4 | } 5 | 6 | fun is_mt(l : List) { 7 | switch l { 8 | case empty { true } 9 | case node(n, next) { false } 10 | } 11 | } 12 | 13 | union A { a } 14 | 15 | 16 | theorem blah : [false] 25 | end -------------------------------------------------------------------------------- /test/parse/ty_params_1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/parse/ty_params_1.pf:16.1-16.18: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/parse/ty_params_1.pf:16.16-16.18: expected closing ">" after type parameters 4 | -------------------------------------------------------------------------------- /test/parse/weird_if.pf: -------------------------------------------------------------------------------- 1 | // TODO: What is going on here? 2 | define a : fn bool -> bool 3 | = fun x { 4 | if x then false 5 | } 6 | 7 | print a(true) 8 | print a(false) 9 | 10 | /// AAHSDLKFJSD:LKFJSDF:LKSDJFD 11 | theorem blah : all b : bool. 12 | if b then true else false 13 | proof 14 | arbitrary b : bool 15 | switch b { 16 | case true assume prop_t { . } 17 | case false assume prop_f { ? } 18 | } 19 | end 20 | 21 | -------------------------------------------------------------------------------- /test/parse/weird_if.pf.err: -------------------------------------------------------------------------------- 1 | false 2 | true 3 | ./test/parse/weird_if.pf:17.32-17.33: incomplete proof 4 | Goal: 5 | false 6 | Advice: 7 | Prove "false" by proving a contradiction: 8 | if you prove both "P" and "not P", 9 | then "apply (recall not P) to (recall P)" proves "false". 10 | 11 | Givens: 12 | prop_f: b = false 13 | -------------------------------------------------------------------------------- /test/should-error/advice_and.pf: -------------------------------------------------------------------------------- 1 | theorem T: false and false 2 | proof 3 | ? 4 | end 5 | -------------------------------------------------------------------------------- /test/should-error/advice_and.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/advice_and.pf:3.3-3.4: incomplete proof 2 | Goal: 3 | (false and false) 4 | Advice: 5 | Prove this logical-and formula by proving each of its parts, 6 | shown below, then combine the proofs with commas. 7 | false 8 | false 9 | -------------------------------------------------------------------------------- /test/should-error/advice_conclude_given.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool. if P then P 2 | proof 3 | arbitrary P:bool 4 | assume p: P 5 | ? 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/advice_conclude_given.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/advice_conclude_given.pf:5.3-5.4: incomplete proof 2 | Goal: 3 | P 4 | 5 | You can conclude the proof with: 6 | conclude P by p 7 | Givens: 8 | p: P 9 | -------------------------------------------------------------------------------- /test/should-error/advice_false.pf: -------------------------------------------------------------------------------- 1 | define P = true 2 | 3 | theorem T: false 4 | proof 5 | ? 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/advice_false.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/advice_false.pf:5.3-5.4: incomplete proof 2 | Goal: 3 | false 4 | Advice: 5 | Prove "false" by proving a contradiction: 6 | if you prove both "P" and "not P", 7 | then "apply (recall not P) to (recall P)" proves "false". 8 | 9 | -------------------------------------------------------------------------------- /test/should-error/advice_or.pf: -------------------------------------------------------------------------------- 1 | theorem T: true or false 2 | proof 3 | ? 4 | end 5 | -------------------------------------------------------------------------------- /test/should-error/advice_or.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/advice_or.pf:3.3-3.4: incomplete proof 2 | Goal: 3 | (true or false) 4 | Advice: 5 | Prove this logical-or formula by proving one of its parts: 6 | true 7 | false 8 | -------------------------------------------------------------------------------- /test/should-error/advice_recall.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool. if P then P 2 | proof 3 | arbitrary P:bool 4 | assume: P 5 | ? 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/advice_recall.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/advice_recall.pf:5.3-5.4: incomplete proof 2 | Goal: 3 | P 4 | 5 | You can conclude the proof with: 6 | recall P 7 | Givens: 8 | _: P 9 | -------------------------------------------------------------------------------- /test/should-error/advice_some.pf: -------------------------------------------------------------------------------- 1 | theorem test: some x : bool. x = x 2 | proof 3 | ? 4 | end 5 | -------------------------------------------------------------------------------- /test/should-error/advice_some.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/advice_some.pf:3.3-3.4: incomplete proof 2 | Goal: 3 | some x:bool. x = x 4 | Advice: 5 | Prove this "some" formula with: 6 | choose A 7 | where you replace A with your choice(s), 8 | then prove: 9 | A = A 10 | -------------------------------------------------------------------------------- /test/should-error/advice_true.pf: -------------------------------------------------------------------------------- 1 | theorem T: true 2 | proof 3 | ? 4 | end 5 | -------------------------------------------------------------------------------- /test/should-error/advice_true.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/advice_true.pf:3.3-3.4: incomplete proof 2 | Goal: 3 | true 4 | Advice: 5 | You can prove "true" with a period. 6 | 7 | -------------------------------------------------------------------------------- /test/should-error/all4.pf: -------------------------------------------------------------------------------- 1 | theorem T: if (all P:bool. P) then (all Q:bool. not Q) 2 | proof 3 | suppose prem 4 | prem 5 | end -------------------------------------------------------------------------------- /test/should-error/all4.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/all4.pf:4.3-4.7: 2 | Could not prove that 3 | P 4 | implies 5 | not P 6 | 7 | While trying to prove that 8 | (all P:bool. P) 9 | implies 10 | (all Q:bool. not Q) 11 | -------------------------------------------------------------------------------- /test/should-error/all5.pf: -------------------------------------------------------------------------------- 1 | theorem T: all x : bool x = x 2 | proof 3 | arbitrary x:bool 4 | conclude x = x by . 5 | end 6 | -------------------------------------------------------------------------------- /test/should-error/all5.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/all5.pf:1.1-1.24: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/should-error/all5.pf:1.25-1.26: expected "." after parameters of "all", not 4 | x 5 | while parsing 6 | term ::= "all" var_list "." term 7 | -------------------------------------------------------------------------------- /test/should-error/all_intro_advice1.pf: -------------------------------------------------------------------------------- 1 | theorem test : all x : bool, y : bool. all z : bool, w : bool. 2 | all n : bool. 3 | x or y or y or not(x) 4 | proof 5 | ? 6 | end -------------------------------------------------------------------------------- /test/should-error/all_intro_advice1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/all_intro_advice1.pf:5.3-5.4: incomplete proof 2 | Goal: 3 | (all x:bool, y:bool. (all z:bool, w:bool. (all n:bool. (x or y or y or not x)))) 4 | Advice: 5 | Prove this "all" formula with: 6 | arbitrary x:bool, y:bool 7 | followed by a proof of: 8 | (all z:bool, w:bool. (all n:bool. (x or y or y or not x))) 9 | -------------------------------------------------------------------------------- /test/should-error/all_intro_advice2.pf: -------------------------------------------------------------------------------- 1 | theorem test : all x : bool. all y : bool. all z : bool. all w : bool. 2 | all n : bool. 3 | x or y or y or not(x) 4 | proof 5 | ? 6 | end -------------------------------------------------------------------------------- /test/should-error/all_intro_advice2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/all_intro_advice2.pf:5.3-5.4: incomplete proof 2 | Goal: 3 | (all x:bool. (all y:bool. (all z:bool. (all w:bool. (all n:bool. (x or y or y or not x)))))) 4 | Advice: 5 | Prove this "all" formula with: 6 | arbitrary x:bool 7 | followed by a proof of: 8 | (all y:bool. (all z:bool. (all w:bool. (all n:bool. (x or y or y or not x))))) 9 | -------------------------------------------------------------------------------- /test/should-error/all_intro_advice3.pf: -------------------------------------------------------------------------------- 1 | theorem test : all x : bool, y : bool, z : bool, w : bool. 2 | all n : bool. 3 | x or y or y or not(x) 4 | proof 5 | arbitrary x : bool 6 | ? 7 | end -------------------------------------------------------------------------------- /test/should-error/all_intro_advice3.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/all_intro_advice3.pf:6.3-6.4: incomplete proof 2 | Goal: 3 | (all y:bool, z:bool, w:bool. (all n:bool. (x or y or y or not x))) 4 | Advice: 5 | Prove this "all" formula with: 6 | arbitrary y:bool, z:bool, w:bool 7 | followed by a proof of: 8 | (all n:bool. (x or y or y or not x)) 9 | -------------------------------------------------------------------------------- /test/should-error/apply_to_error.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. 2 | if (P and Q and R) then ((if P then Q) and (if Q then R)) 3 | proof 4 | arbitrary P:bool, Q:bool, R:bool 5 | suppose prem 6 | have ptq : if P then Q by suppose P prem 7 | have qtr : if Q then R by suppose Q prem 8 | ptq, qtr 9 | end 10 | 11 | 12 | theorem t2: all P:bool, Q:bool, R:bool. 13 | if (P and Q and R) then P and R 14 | proof 15 | arbitrary P:bool, Q:bool, R:bool 16 | suppose prem : P and Q and R 17 | have step : (if P then Q) and (if Q then R) by apply T[P, Q, R] prem 18 | apply step to prem 19 | end 20 | -------------------------------------------------------------------------------- /test/should-error/apply_to_error.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/apply_to_error.pf:17.3-17.66: while parsing 2 | proof_stmt ::= "have" identifier ":" formula "by" proof 3 | proof_stmt ::= "have" ":" formula "by" proof 4 | 5 | ./test/should-error/apply_to_error.pf:17.50-17.66: while parsing apply-to (use a logical implication) 6 | conclusion ::= "apply" proof "to" proof 7 | 8 | ./test/should-error/apply_to_error.pf:17.67-17.71: expected "to" after implication part of "apply", not 9 | prem 10 | -------------------------------------------------------------------------------- /test/should-error/array2.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | define L = [1,2,3] 5 | define A = array(L) 6 | assert A[3] = 1 // out of bounds 7 | 8 | -------------------------------------------------------------------------------- /test/should-error/array2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/array2.pf:6.1-6.16: assertion failed: 2 | array(1, 2, 3)[3] ≠ 1 3 | 4 | -------------------------------------------------------------------------------- /test/should-error/block_comment.pf: -------------------------------------------------------------------------------- 1 | /******* 2 | ********/ 3 | 4 | assert false 5 | 6 | 7 | /******* 8 | *******/ -------------------------------------------------------------------------------- /test/should-error/block_comment.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/block_comment.pf:4.1-4.13: assertion failed: false 2 | -------------------------------------------------------------------------------- /test/should-error/cases_error.pf: -------------------------------------------------------------------------------- 1 | theorem T: if false or false then false 2 | proof 3 | suppose ForF { 4 | cases 5 | case F { F } 6 | case F { F } 7 | } 8 | end 9 | -------------------------------------------------------------------------------- /test/should-error/cases_error.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/cases_error.pf:1.1-4.10: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/should-error/cases_error.pf:4.5-4.10: while parsing cases (use a logical or) 4 | conclusion ::= "cases" proof case_clause* 5 | case_clause ::= "case" identifier ":" term "{" proof "}" 6 | 7 | ./test/should-error/cases_error.pf:5.5-5.9: expected a proof. 8 | Did you mean "cases" instead of "case"? 9 | -------------------------------------------------------------------------------- /test/should-error/comma_question.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool. if P then P and Q 2 | proof 3 | arbitrary P:bool, Q:bool 4 | assume p: P 5 | p , ? 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/comma_question.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/comma_question.pf:5.7-5.8: incomplete proof 2 | Goal: 3 | Q 4 | 5 | 6 | Givens: 7 | p: P 8 | -------------------------------------------------------------------------------- /test/should-error/conclude.pf: -------------------------------------------------------------------------------- 1 | theorem T: false 2 | proof 3 | conclude false by 4 | end 5 | -------------------------------------------------------------------------------- /test/should-error/conclude.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/conclude.pf:4.1-4.4: incomplete proof 2 | Goal: 3 | false 4 | Advice: 5 | Prove "false" by proving a contradiction: 6 | if you prove both "P" and "not P", 7 | then "apply (recall not P) to (recall P)" proves "false". 8 | 9 | -------------------------------------------------------------------------------- /test/should-error/conjunct.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | define num = 0 7 | 8 | theorem blah: all a : bool, b : bool. 9 | if a and b then a 10 | proof 11 | arbitrary a : bool, b : bool 12 | suppose prem 13 | conjunct num of prem 14 | end -------------------------------------------------------------------------------- /test/should-error/conjunct.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/conjunct.pf:8.1-13.11: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/should-error/conjunct.pf:13.12-13.15: expected an int literal after "conjunct", not 4 | num 5 | -------------------------------------------------------------------------------- /test/should-error/deep_error.pf: -------------------------------------------------------------------------------- 1 | define x = foo(bar(baz(jaz(kool(1 2))))) 2 | -------------------------------------------------------------------------------- /test/should-error/deep_error.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/deep_error.pf:1.24-1.34: while parsing function call 2 | term ::= term "(" term_list ")" 3 | 4 | ./test/should-error/deep_error.pf:1.28-1.34: while parsing function call 5 | term ::= term "(" term_list ")" 6 | 7 | ./test/should-error/deep_error.pf:1.28-1.34: expected closing parenthesis ")", not 8 | 2 9 | Perhaps you forgot a comma? 10 | -------------------------------------------------------------------------------- /test/should-error/def_generic_terminst.pf: -------------------------------------------------------------------------------- 1 | union A { 2 | a 3 | } 4 | 5 | lemma L1: true 6 | proof 7 | . 8 | end 9 | 10 | lemma L2: true 11 | proof 12 | expand a. 13 | end 14 | -------------------------------------------------------------------------------- /test/should-error/def_generic_terminst.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/def_generic_terminst.pf:12.3-12.11: could not find definition of a 2 | -------------------------------------------------------------------------------- /test/should-error/def_proof_var.pf: -------------------------------------------------------------------------------- 1 | lemma L1: true 2 | proof 3 | . 4 | end 5 | 6 | lemma L2: true 7 | proof 8 | expand L1. 9 | end 10 | -------------------------------------------------------------------------------- /test/should-error/def_proof_var.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/def_proof_var.pf:8.3-8.12: Expected a term or a type variable when attempting to expand L1. 2 | If L1 is a theorem or a lemma, you might want to use 'replace' 3 | -------------------------------------------------------------------------------- /test/should-error/define_missing_semi.pf: -------------------------------------------------------------------------------- 1 | union Bit { 2 | zero 3 | one 4 | } 5 | 6 | recursive f(Bit) -> Bit { 7 | f(zero) = one 8 | f(one) = define z = zero 9 | z 10 | } 11 | -------------------------------------------------------------------------------- /test/should-error/define_missing_semi.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/define_missing_semi.pf:8.3-8.27: while parsing 2 | fun_case ::= identifier "(" param_list ")" "=" term 3 | 4 | ./test/should-error/define_missing_semi.pf:8.12-8.27: while parsing 5 | term ::= "define" identifier "=" term ";" term 6 | 7 | ./test/should-error/define_missing_semi.pf:9.12-9.13: expected ";" after right-hand side of "define", not 8 | "z" 9 | -------------------------------------------------------------------------------- /test/should-error/define_proof_missing_term.pf: -------------------------------------------------------------------------------- 1 | theorem T: true 2 | proof 3 | define x = 4 | . 5 | end 6 | -------------------------------------------------------------------------------- /test/should-error/define_proof_missing_term.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/define_proof_missing_term.pf:1.1-3.13: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/should-error/define_proof_missing_term.pf:3.3-3.13: while parsing 4 | proof_stmt ::= "define" identifier "=" term 5 | 6 | ./test/should-error/define_proof_missing_term.pf:4.3-4.4: expected a term, not 7 | "." 8 | -------------------------------------------------------------------------------- /test/should-error/define_type.pf: -------------------------------------------------------------------------------- 1 | define x : = 5 2 | -------------------------------------------------------------------------------- /test/should-error/define_type.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/define_type.pf:1.1-1.11: while parsing 2 | proof_stmt ::= "define" identifier ":" type "=" term 3 | 4 | ./test/should-error/define_type.pf:1.12-1.13: expected a type, not 5 | "=" 6 | -------------------------------------------------------------------------------- /test/should-error/definition1.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | import UInt 4 | 5 | theorem T: all xs:List. if length(xs) = 0 then false 6 | proof 7 | arbitrary xs:List 8 | assume: (length(xs) = 0) 9 | have X: ? by expand length in recall (length(xs) = 0) 10 | ? 11 | end 12 | -------------------------------------------------------------------------------- /test/should-error/definition1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/definition1.pf:9.16-9.56: could not find a place to expand definition of length in: 2 | length(xs) = 0 3 | -------------------------------------------------------------------------------- /test/should-error/double_private.pf: -------------------------------------------------------------------------------- 1 | private private define X: bool = true -------------------------------------------------------------------------------- /test/should-error/double_private.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/double_private.pf:1.9-1.16: expected a statement, not 2 | private 3 | -------------------------------------------------------------------------------- /test/should-error/equality.pf: -------------------------------------------------------------------------------- 1 | union List { 2 | empty 3 | node(T, List) 4 | } 5 | 6 | union A { a } 7 | union B { b } 8 | 9 | assert not (@[] = @[]) 10 | -------------------------------------------------------------------------------- /test/should-error/equality.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/equality.pf:9.13-9.28: expected arguments of equality to have the same type, but 2 | List ≠ List 3 | -------------------------------------------------------------------------------- /test/should-error/eval-goal2.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | theorem T: 1 + 2 + 3 = 2 + 2 + 1 4 | proof 5 | evaluate 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/eval-goal2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/eval-goal2.pf:5.3-5.11: the goal did not evaluate to `true`, but instead: 2 | false 3 | -------------------------------------------------------------------------------- /test/should-error/fn_missing_arrow.pf: -------------------------------------------------------------------------------- 1 | define f : fn bool bool = fun x { not x } 2 | assert f(false) 3 | -------------------------------------------------------------------------------- /test/should-error/fn_missing_arrow.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/fn_missing_arrow.pf:1.1-1.19: while parsing 2 | proof_stmt ::= "define" identifier ":" type "=" term 3 | 4 | ./test/should-error/fn_missing_arrow.pf:1.12-1.19: while parsing 5 | type ::= "fn" type_params_opt type_list "->" type 6 | 7 | ./test/should-error/fn_missing_arrow.pf:1.20-1.24: expected "->" after parameter types, not 8 | "bool" 9 | -------------------------------------------------------------------------------- /test/should-error/foldr_sum.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import List 3 | 4 | recursive sum(List) -> Nat { 5 | sum(empty) = ℕ0 6 | sum(node(n, ns)) = n + sum(ns) 7 | } 8 | 9 | // also lalr parser error 10 | theorem foldr_eq_sum : all ls : List. sum(ls) = foldr(ls, ℕ0, operator +) 11 | proof 12 | induction List 13 | case empty { 14 | expand foldr | sum. 15 | } 16 | case node(a, d) suppose IH { 17 | expand foldr 18 | ? 19 | } 20 | end 21 | -------------------------------------------------------------------------------- /test/should-error/foldr_sum.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/foldr_sum.pf:18.5-18.6: incomplete proof 2 | Goal: 3 | sum(node(a, d)) = a + foldr(d, ℕ0, operator +) 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | Givens: 11 | IH: sum(d) = foldr(d, ℕ0, operator +) 12 | -------------------------------------------------------------------------------- /test/should-error/forgot_def.pf: -------------------------------------------------------------------------------- 1 | define xor : fn bool, bool -> bool 2 | = fun P, Q { if P then (not Q) else Q } 3 | 4 | theorem neq_xor : all P : bool, Q : bool. 5 | if P /= Q then xor(P, Q) 6 | proof 7 | suffices ? by xor 8 | end -------------------------------------------------------------------------------- /test/should-error/forgot_def.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/forgot_def.pf:7.17-7.20: expected a proof but instead got term `xor`. 2 | Perhaps you meant `expand xor`? 3 | -------------------------------------------------------------------------------- /test/should-error/forgot_def_pvar.pf: -------------------------------------------------------------------------------- 1 | // Definitely not Nat 2 | union Blah { 3 | A 4 | B(Blah) 5 | } 6 | 7 | recursive even(Blah) -> bool { 8 | even(A) = true 9 | even(B(b)) = not(even(b)) 10 | } 11 | 12 | theorem not_B_even : all n : Blah. 13 | (not even(n)) = even(B(n)) 14 | proof 15 | even 16 | end -------------------------------------------------------------------------------- /test/should-error/forgot_def_pvar.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/forgot_def_pvar.pf:15.3-15.7: expected a proof but instead got term `even`. 2 | Perhaps you meant `expand even`? 3 | -------------------------------------------------------------------------------- /test/should-error/forgot_def_rec.pf: -------------------------------------------------------------------------------- 1 | // Definitely not Nat 2 | union Blah { 3 | A 4 | B(Blah) 5 | } 6 | 7 | recursive even(Blah) -> bool { 8 | even(A) = true 9 | even(B(b)) = not(even(b)) 10 | } 11 | 12 | theorem not_B_even : all n : Blah. 13 | if even(n) then not (even(B(n))) 14 | proof 15 | arbitrary n : Blah 16 | suffices if even(n) then not not even(n) by even 17 | end -------------------------------------------------------------------------------- /test/should-error/forgot_def_rec.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/forgot_def_rec.pf:16.47-16.51: expected a proof but instead got term `even`. 2 | Perhaps you meant `expand even`? 3 | -------------------------------------------------------------------------------- /test/should-error/forgot_replace_all.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | define bigO : fn (fn Nat -> Nat), (fn Nat -> Nat) -> bool = 4 | fun f, g{ all x : Nat. some k : Nat, c : Nat. if x >= k then f(x) <= c * g(x) } 5 | 6 | theorem n_big_o_n2 : bigO(fun x { x }, fun x { x * x }) 7 | proof 8 | suffices (all x:Nat. some k:Nat,c:Nat. (if x ≥ k then x ≤ c * (x * x))) 9 | by expand bigO. 10 | arbitrary x : Nat 11 | choose ℕ1, ℕ1 12 | suffices if x ≥ ℕ1 then x ≤ x * x 13 | by one_mult 14 | assume prem : x >= ℕ1 15 | have one_le_x : ℕ1 <= x by expand operator>= in prem 16 | have x_le_xx : x * ℕ1 <= x * x by apply mult_mono_le[x, ℕ1, x] to one_le_x 17 | conclude x <= x * x by replace mult_one[x] in x_le_xx 18 | end 19 | -------------------------------------------------------------------------------- /test/should-error/forgot_replace_all.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/forgot_replace_all.pf:13.8-13.16: 2 | Could not prove that 3 | (all n:Nat. ℕ1 * n = n) 4 | instantiates to 5 | (if (if x ≥ ℕ1 then x ≤ x * x) then (if x ≥ ℕ1 then x ≤ ℕ1 * x * x)) 6 | because 7 | ./test/should-error/forgot_replace_all.pf:13.8-13.16: formula: (if (if x ≥ ℕ1 then x ≤ x * x) then (if x ≥ ℕ1 then x ≤ ℕ1 * x * x)) 8 | does not match expected formula: ℕ1 * n = n 9 | Did you mean `replace one_mult`? 10 | -------------------------------------------------------------------------------- /test/should-error/forgot_replace_allelim.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | define bigO : fn (fn Nat -> Nat), (fn Nat -> Nat) -> bool = 4 | fun f, g{ all x : Nat. some k : Nat, c : Nat. if x >= k then f(x) <= c * g(x) } 5 | 6 | theorem n_big_o_n2 : bigO(fun x { x }, fun x { x * x }) 7 | proof 8 | suffices (all x:Nat. some k:Nat,c:Nat. (if x ≥ k then x ≤ c * (x * x))) 9 | by expand bigO. 10 | arbitrary x : Nat 11 | choose ℕ1, ℕ1 12 | suffices if x ≥ ℕ1 then x ≤ x * x 13 | by one_mult[x*x] 14 | assume prem : x >= ℕ1 15 | have one_le_x : ℕ1 <= x by expand operator>= in prem 16 | have x_le_xx : x * ℕ1 <= x * x by apply mult_mono_le[x, ℕ1, x] to one_le_x 17 | conclude x <= x * x by replace mult_one[x] in x_le_xx 18 | end 19 | -------------------------------------------------------------------------------- /test/should-error/forgot_replace_allelim.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/forgot_replace_allelim.pf:13.8-13.21: 2 | Could not prove that 3 | ℕ1 * x * x = x * x 4 | implies 5 | (if (if x ≥ ℕ1 then x ≤ x * x) then (if x ≥ ℕ1 then x ≤ ℕ1 * x * x)) 6 | Did you mean `replace one_mult[x * x]`? 7 | -------------------------------------------------------------------------------- /test/should-error/forgot_replace_recall.pf: -------------------------------------------------------------------------------- 1 | theorem blah : all A : bool, B : bool. 2 | if A = B then B = A 3 | proof 4 | arbitrary A : bool, B : bool 5 | assume prem 6 | recall A = B 7 | end -------------------------------------------------------------------------------- /test/should-error/forgot_replace_recall.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/forgot_replace_recall.pf:6.3-6.15: error, the proved formula: 2 | A = B 3 | does not match the goal: 4 | B = A 5 | because 6 | A 7 | ≠ B 8 | 9 | Did you mean `replace recall A = B`? 10 | -------------------------------------------------------------------------------- /test/should-error/function_case_missing_equal.pf: -------------------------------------------------------------------------------- 1 | union Bit { 2 | zero 3 | one 4 | } 5 | 6 | recursive f(Bit) -> Bit { 7 | f(zero) = one 8 | f(one) zero 9 | } 10 | -------------------------------------------------------------------------------- /test/should-error/function_case_missing_equal.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/function_case_missing_equal.pf:6.1-8.9: while parsing 2 | statement ::= "recursive" identifier type_params_opt "(" type_list ")" 3 | "->" type "{" fun_case* "}" 4 | 5 | ./test/should-error/function_case_missing_equal.pf:8.3-8.9: while parsing 6 | fun_case ::= identifier "(" param_list ")" "=" term 7 | 8 | ./test/should-error/function_case_missing_equal.pf:8.10-8.14: expected "=" and then a term, not 9 | zero 10 | -------------------------------------------------------------------------------- /test/should-error/function_not_union.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/function_not_union.pf:1.12-1.16: expected a union type but instead got bool 2 | -------------------------------------------------------------------------------- /test/should-error/have_remove_marks.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | import UInt 4 | 5 | theorem blah : all x : Nat. 6 | length(node(x, empty)) = 1 7 | proof 8 | arbitrary x : Nat 9 | have step : length(@empty) + #length(@empty)# 10 | = length(@empty) + 0 11 | by expand length. 12 | ? 13 | end 14 | -------------------------------------------------------------------------------- /test/should-error/have_remove_marks.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/have_remove_marks.pf:12.3-12.4: incomplete proof 2 | Goal: 3 | length([x]) = 1 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | Givens: 11 | step: length(@[]) + length(@[]) = length(@[]) + 0 12 | -------------------------------------------------------------------------------- /test/should-error/help1.pf: -------------------------------------------------------------------------------- 1 | theorem T: false 2 | proof 3 | have x: all P:bool. if P then P by { 4 | arbitrary P:bool 5 | assume p 6 | p 7 | } 8 | help x 9 | end 10 | -------------------------------------------------------------------------------- /test/should-error/help1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/help1.pf:8.3-8.9: Advice about using fact: 2 | (all P:bool. (if P then P)) 3 | 4 | Instantiate this all formula with your choice for P 5 | by writing it in square-brackets like so: 6 | x[A] 7 | to obtain a proof of: 8 | (if A then A) 9 | -------------------------------------------------------------------------------- /test/should-error/help2.pf: -------------------------------------------------------------------------------- 1 | define X = true 2 | define Y = false 3 | 4 | theorem T: X 5 | proof 6 | have x1: X by expand X. 7 | have x2: X or Y by x1 8 | help x2 9 | end 10 | -------------------------------------------------------------------------------- /test/should-error/help2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/help2.pf:8.3-8.10: Advice about using fact: 2 | (X or Y) 3 | 4 | Use this logical-or by proceeding with a "cases" statement: 5 | cases x2 6 | case label_0 : X { ? } 7 | case label_1 : Y { ? } 8 | -------------------------------------------------------------------------------- /test/should-error/help3.pf: -------------------------------------------------------------------------------- 1 | theorem T: true 2 | proof 3 | have s1: some x : bool. x = true 4 | by choose true reflexive 5 | help s1 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/help3.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/help3.pf:5.3-5.10: Advice about using fact: 2 | some x:bool. x = true 3 | 4 | To use this "some" formula, proceed with: 5 | obtain A where label: A = true from s1 6 | where A is a new name of your choice, 7 | followed by a proof of the goal. 8 | -------------------------------------------------------------------------------- /test/should-error/help4.pf: -------------------------------------------------------------------------------- 1 | theorem T: true 2 | proof 3 | have a1: all x : bool. if x = true then true = x by 4 | arbitrary x:bool 5 | assume: x = true 6 | symmetric (recall x = true) 7 | 8 | help a1[true] 9 | end 10 | -------------------------------------------------------------------------------- /test/should-error/help4.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/help4.pf:8.3-8.16: Advice about using fact: 2 | (if true = true then true = true) 3 | 4 | Apply this if-then formula to a proof of its premise: 5 | true = true 6 | to obtain a proof of its conclusion: 7 | true = true 8 | by using an apply-to statement: 9 | apply a1[true] to ? 10 | -------------------------------------------------------------------------------- /test/should-error/iff_precedence.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool. P ⇔ (P = true) 2 | proof 3 | ? 4 | end 5 | 6 | -------------------------------------------------------------------------------- /test/should-error/iff_precedence.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/iff_precedence.pf:3.3-3.4: incomplete proof 2 | Goal: 3 | (all P:bool. (P ⇔ (P = true))) 4 | Advice: 5 | Prove this "all" formula with: 6 | arbitrary P:bool 7 | followed by a proof of: 8 | (P ⇔ (P = true)) 9 | -------------------------------------------------------------------------------- /test/should-error/import_lemma.pf: -------------------------------------------------------------------------------- 1 | import Private 2 | 3 | theorem T: true 4 | proof 5 | cant_import_lemma 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/import_lemma.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/import_lemma.pf:5.3-5.20: undefined proof variable cant_import_lemma 2 | -------------------------------------------------------------------------------- /test/should-error/induction2.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | union Tree { 4 | empty(bool) 5 | node(Tree, Nat,Tree) 6 | } 7 | 8 | recursive size(Tree) -> Nat { 9 | size(empty) = ℕ0 10 | size(node(L, n, R)) = ℕ1 + size(L) + size(R) 11 | } 12 | 13 | theorem tree_size: all T:Tree. size(T) = size(T) 14 | proof 15 | ? 16 | end 17 | -------------------------------------------------------------------------------- /test/should-error/induction2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/induction2.pf:15.3-15.4: incomplete proof 2 | Goal: 3 | (all T:Tree. size(T) = size(T)) 4 | Advice: 5 | Prove this "all" formula with: 6 | arbitrary T:Tree 7 | followed by a proof of: 8 | size(T) = size(T) 9 | 10 | Alternatively, you can try induction with: 11 | induction Tree 12 | case empty(b1) { 13 | ? 14 | } 15 | case node(T1, N2, T3) assume IH1: size(T1) = size(T1), 16 | IH2: size(T3) = size(T3) { 17 | ? 18 | } 19 | 20 | -------------------------------------------------------------------------------- /test/should-error/induction_advice_partial.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | union NatList { 7 | null 8 | cons(Nat, NatList) 9 | } 10 | 11 | recursive length(NatList) -> Nat { 12 | length(null) = zero 13 | length(cons(a, d)) = suc(length(d)) 14 | } 15 | 16 | theorem add_one_length : all ls : NatList, n : Nat. 17 | suc(length(ls)) = length(cons(n, ls)) 18 | proof 19 | induction NatList 20 | case null { 21 | ? 22 | } 23 | case cons(a, d) suppose IH { 24 | ? 25 | } 26 | end 27 | -------------------------------------------------------------------------------- /test/should-error/induction_advice_partial.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/induction_advice_partial.pf:21.5-21.6: incomplete proof 2 | Goal: 3 | (all n:Nat. suc(length(null)) = length(cons(n, null))) 4 | Advice: 5 | Prove this "all" formula with: 6 | arbitrary n:Nat 7 | followed by a proof of: 8 | suc(length(null)) = length(cons(n, null)) 9 | 10 | Alternatively, you can try induction with: 11 | induction Nat 12 | case zero { 13 | ? 14 | } 15 | case suc(N1) assume IH1: suc(length(null)) = length(cons(N1, null)) { 16 | ? 17 | } 18 | 19 | -------------------------------------------------------------------------------- /test/should-error/induction_case.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | union NatList { 7 | null 8 | cons(Nat, NatList) 9 | } 10 | 11 | recursive length(NatList) -> Nat { 12 | length(null) = zero 13 | length(cons(a, d)) = suc(length(d)) 14 | } 15 | 16 | theorem add_one_length : all ls : NatList, n : Nat. 17 | suc(length(ls)) = length(cons(n, ls)) 18 | proof 19 | induction NatList 20 | case null { } 21 | case cons(a, d) suppose IH { ? } 22 | end 23 | -------------------------------------------------------------------------------- /test/should-error/induction_case.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/induction_case.pf:20.15-20.16: incomplete proof 2 | Goal: 3 | (all n:Nat. suc(length(null)) = length(cons(n, null))) 4 | Advice: 5 | Prove this "all" formula with: 6 | arbitrary n:Nat 7 | followed by a proof of: 8 | suc(length(null)) = length(cons(n, null)) 9 | 10 | Alternatively, you can try induction with: 11 | induction Nat 12 | case zero { 13 | ? 14 | } 15 | case suc(N1) assume IH1: suc(length(null)) = length(cons(N1, null)) { 16 | ? 17 | } 18 | 19 | -------------------------------------------------------------------------------- /test/should-error/injective1.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | define one = ℕ1 4 | 5 | theorem T: one = ℕ1 6 | proof 7 | injective one 8 | ? 9 | end 10 | -------------------------------------------------------------------------------- /test/should-error/injective1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/injective1.pf:7.3-7.16: in injective, expected a constructor, not 2 | one 3 | -------------------------------------------------------------------------------- /test/should-error/inst-type-square-bracket.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | 4 | theorem thm: if ( all xs:List. map(xs, fun x:T { x }) = xs) 5 | then map(node(ℕ1, empty), fun x:Nat { x }) = node(ℕ1, empty) 6 | proof 7 | suppose prem: ( all xs:List. map(xs, fun x:T { x }) = xs) 8 | prem[Nat][node(ℕ1,empty)] 9 | end 10 | -------------------------------------------------------------------------------- /test/should-error/inst-type-square-bracket.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/inst-type-square-bracket.pf:8.3-8.12: to instantiate: 2 | prem : (all T:type. (all xs:List. map(xs, fun x:T { x }) = xs)) 3 | with type arguments, instead write: 4 | prem 5 | 6 | -------------------------------------------------------------------------------- /test/should-error/inst_type_forget.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | 4 | theorem thm: if ( all xs:List. map(xs, fun x:T { x }) = xs) 5 | then map(node(ℕ1, empty), fun x:Nat { x }) = node(ℕ1, empty) 6 | proof 7 | suppose prem: ( all xs:List. map(xs, fun x:T { x }) = xs) 8 | prem[node(ℕ1,empty)] 9 | end 10 | -------------------------------------------------------------------------------- /test/should-error/inst_type_forget.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/inst_type_forget.pf:8.3-8.23: In instantiation of 2 | prem : (all T:type. (all xs:List. map(xs, fun x:T { x }) = xs)) 3 | expected a type argument, but was given 'node(ℕ1, [])' 4 | -------------------------------------------------------------------------------- /test/should-error/int2.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import Int 3 | 4 | // Testing printing of integers 5 | theorem T: +0 + -0 + +1 + -1 + 1 = +1 6 | proof 7 | ? 8 | end 9 | 10 | -------------------------------------------------------------------------------- /test/should-error/int2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/int2.pf:7.3-7.4: incomplete proof 2 | Goal: 3 | (((+0 + - 0) + +1) + - 1) + 1 = +1 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | -------------------------------------------------------------------------------- /test/should-error/int_error_for_now.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/int_error_for_now.pf:9.12-9.13: expected Int but the call returns Nat 2 | -------------------------------------------------------------------------------- /test/should-error/lambda_synth.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | define area = λ h, w { h * w } 4 | -------------------------------------------------------------------------------- /test/should-error/lambda_synth.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/lambda_synth.pf:3.15-3.31: Cannot synthesize a type for fun h,w { h * w }. 2 | Add type annotations to the parameters. 3 | -------------------------------------------------------------------------------- /test/should-error/len_termination.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | union NatList { 4 | Empty 5 | Node(Nat, NatList) 6 | } 7 | 8 | define L = Node(ℕ7, Node(ℕ4, Node (ℕ5, Empty))) 9 | 10 | recursive len(NatList) -> Nat { 11 | len(Empty) = ℕ0 12 | len(Node(n, ls)) = ℕ1 + len(L) 13 | } 14 | -------------------------------------------------------------------------------- /test/should-error/len_termination.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/len_termination.pf:12.27-12.33: ill-formed recursive call 2 | expected first argument to be n or ls, not L 3 | -------------------------------------------------------------------------------- /test/should-error/length_drop.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | 4 | theorem length_drop2 : all n : Nat, xs : List. 5 | length_nat(drop(n, xs)) = length_nat(xs) ∸ n 6 | proof 7 | arbitrary T:type 8 | induction Nat 9 | case 0 { 10 | arbitrary xs : List 11 | suffices length_nat(xs) = length_nat(xs) ∸ ℕ0 by expand drop. 12 | replace monus_zero[length_nat(xs)]. 13 | } 14 | case suc(n') assume IH { 15 | arbitrary xs : List 16 | // Make sure TermInst is explicit around the empty list. 17 | expand drop 18 | ? 19 | } 20 | end 21 | -------------------------------------------------------------------------------- /test/should-error/length_drop.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/length_drop.pf:18.5-18.6: incomplete proof 2 | Goal: 3 | length_nat(switch xs { case [] { @[] } case node(x, xs') { drop(n', xs') } }) = length_nat(xs) ∸ suc(n') 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | Givens: 11 | IH: (all xs:List. length_nat(drop(n', xs)) = length_nat(xs) ∸ n') 12 | -------------------------------------------------------------------------------- /test/should-error/missing-colon-in-have.pf: -------------------------------------------------------------------------------- 1 | theorem T: true 2 | proof 3 | have true by . 4 | . 5 | end 6 | -------------------------------------------------------------------------------- /test/should-error/missing-colon-in-have.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/missing-colon-in-have.pf:1.1-3.7: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/should-error/missing-colon-in-have.pf:3.3-3.7: while parsing 4 | proof_stmt ::= "have" identifier ":" formula "by" proof 5 | proof_stmt ::= "have" ":" formula "by" proof 6 | 7 | ./test/should-error/missing-colon-in-have.pf:3.8-3.12: expected an identifier or colon after "have", not 8 | true 9 | -------------------------------------------------------------------------------- /test/should-error/missing-conclusion-subproof.pf: -------------------------------------------------------------------------------- 1 | theorem t : true 2 | proof 3 | have blah : all b : bool. true 4 | by arbitrary b : bool 5 | end -------------------------------------------------------------------------------- /test/should-error/missing-conclusion-subproof.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/missing-conclusion-subproof.pf:5.1-5.4: incomplete proof 2 | Goal: 3 | true 4 | Advice: 5 | You can prove "true" with a period. 6 | 7 | -------------------------------------------------------------------------------- /test/should-error/missing-conclusion.pf: -------------------------------------------------------------------------------- 1 | theorem T: true 2 | proof 3 | have X: true by . 4 | have Y: true by . 5 | end 6 | -------------------------------------------------------------------------------- /test/should-error/missing-conclusion.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/missing-conclusion.pf:5.1-5.4: incomplete proof 2 | Goal: 3 | true 4 | Advice: 5 | You can prove "true" with a period. 6 | 7 | Givens: 8 | Y: true, 9 | X: true 10 | -------------------------------------------------------------------------------- /test/should-error/missing-conclusion1.pf: -------------------------------------------------------------------------------- 1 | theorem T : true 2 | proof 3 | end -------------------------------------------------------------------------------- /test/should-error/missing-conclusion1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/missing-conclusion1.pf:3.1-3.4: incomplete proof 2 | Goal: 3 | true 4 | Advice: 5 | You can prove "true" with a period. 6 | 7 | -------------------------------------------------------------------------------- /test/should-error/missing_generic.pf: -------------------------------------------------------------------------------- 1 | define id_gen : fn E -> E = fun x { x } -------------------------------------------------------------------------------- /test/should-error/missing_generic.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/missing_generic.pf:1.32-1.43: Expected type parameter E, but got a lambda. 2 | Add generic E { ... } around the function body. 3 | -------------------------------------------------------------------------------- /test/should-error/missing_recall.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool. if P then P 2 | proof 3 | arbitrary P:bool 4 | assume: P 5 | P 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/missing_recall.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/missing_recall.pf:5.3-5.4: expected a proof but instead got term `P`. 2 | Perhaps you meant `recall P`? 3 | -------------------------------------------------------------------------------- /test/should-error/mutual_termination.pf: -------------------------------------------------------------------------------- 1 | union Fruit { 2 | apple 3 | orange 4 | } 5 | 6 | recursive f(Fruit) -> Fruit { 7 | f(apple) = g(orange) 8 | f(orange) = g(apple) 9 | } 10 | 11 | recursive g(Fruit) -> Fruit { 12 | g(apple) = f(orange) 13 | g(orange) = f(apple) 14 | } 15 | assert g(apple) = apple 16 | -------------------------------------------------------------------------------- /test/should-error/mutual_termination.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/mutual_termination.pf:7.14-7.15: undefined variable: g 2 | did you intend: ≠, =, f 3 | 4 | -------------------------------------------------------------------------------- /test/should-error/noimport1.pf: -------------------------------------------------------------------------------- 1 | print(42) -------------------------------------------------------------------------------- /test/should-error/noimport1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/noimport1.pf:1.7-1.9: undefined variable: dub_inc 2 | Add `import UInt` to supply a definition. 3 | -------------------------------------------------------------------------------- /test/should-error/noimport2.pf: -------------------------------------------------------------------------------- 1 | print(0) -------------------------------------------------------------------------------- /test/should-error/noimport2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/noimport2.pf:1.7-1.8: undefined variable: bzero 2 | Add `import UInt` to supply a definition. 3 | -------------------------------------------------------------------------------- /test/should-error/noimport3.pf: -------------------------------------------------------------------------------- 1 | print([]) -------------------------------------------------------------------------------- /test/should-error/noimport3.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/noimport3.pf:1.7-1.8: undefined variable: empty 2 | Add `import List` to supply a definition. 3 | -------------------------------------------------------------------------------- /test/should-error/noimport4.pf: -------------------------------------------------------------------------------- 1 | print([42]) -------------------------------------------------------------------------------- /test/should-error/noimport4.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/noimport4.pf:1.10-1.11: undefined variable: node 2 | Add `import List` to supply a definition. 3 | -------------------------------------------------------------------------------- /test/should-error/opaque_define_use_in_theorem.pf: -------------------------------------------------------------------------------- 1 | import OpaqueTests 2 | 3 | theorem aTheorem: f_id(Z) = Z 4 | proof 5 | expand f_id. 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/opaque_define_use_in_theorem.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/opaque_define_use_in_theorem.pf:5.3-5.14: Cannot expand opaque definition of f_id 2 | -------------------------------------------------------------------------------- /test/should-error/opaque_evaluate.pf: -------------------------------------------------------------------------------- 1 | import OpaqueTests 2 | 3 | theorem aTheorem: f_id(Z) = Z 4 | proof 5 | evaluate 6 | end -------------------------------------------------------------------------------- /test/should-error/opaque_evaluate.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/opaque_evaluate.pf:5.5-5.13: the goal did not evaluate to `true`, but instead: 2 | f_id(Z) = Z 3 | -------------------------------------------------------------------------------- /test/should-error/opaque_genrec_use_in_theorem.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import OpaqueTests 3 | 4 | theorem some_theorem_again: fact(ℕ0) = ℕ1 5 | proof 6 | expand fact. 7 | end 8 | -------------------------------------------------------------------------------- /test/should-error/opaque_genrec_use_in_theorem.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/opaque_genrec_use_in_theorem.pf:6.5-6.16: Cannot expand opaque definition of fact 2 | -------------------------------------------------------------------------------- /test/should-error/opaque_induction.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import OpaqueTests 3 | 4 | theorem isomorphic: all x:Nat_Hat. natToNatHat(NatHatToNat(x)) = x 5 | proof 6 | ? 7 | end -------------------------------------------------------------------------------- /test/should-error/opaque_induction.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/opaque_induction.pf:6.5-6.6: incomplete proof 2 | Goal: 3 | (all x:Nat_Hat. natToNatHat(NatHatToNat(x)) = x) 4 | Advice: 5 | Prove this "all" formula with: 6 | arbitrary x:Nat_Hat 7 | followed by a proof of: 8 | natToNatHat(NatHatToNat(x)) = x 9 | -------------------------------------------------------------------------------- /test/should-error/opaque_recursive_use_in_theorem.pf: -------------------------------------------------------------------------------- 1 | import OpaqueTests 2 | 3 | theorem always_Z: all b:Byte. f_z(b) = Z 4 | proof 5 | expand f_z. 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/opaque_recursive_use_in_theorem.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/opaque_recursive_use_in_theorem.pf:5.5-5.15: Cannot expand opaque definition of f_z 2 | -------------------------------------------------------------------------------- /test/should-error/opaque_union_pattern_matching.pf: -------------------------------------------------------------------------------- 1 | import OpaqueTests 2 | 3 | recursive addAgain(Nat_Hat, Nat_Hat) -> Nat_Hat { 4 | addAgain(cero, y) = y 5 | addAgain(next(x), y) = next(addAgain(x, y)) 6 | } 7 | -------------------------------------------------------------------------------- /test/should-error/opaque_union_pattern_matching.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/opaque_union_pattern_matching.pf:4.14-4.18: undefined variable: cero 2 | did you intend: zero 3 | 4 | -------------------------------------------------------------------------------- /test/should-error/opaque_union_use_in_theorem.pf: -------------------------------------------------------------------------------- 1 | import OpaqueTests 2 | 3 | theorem thm: cero = cero 4 | proof 5 | . 6 | end -------------------------------------------------------------------------------- /test/should-error/opaque_union_use_in_theorem.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/opaque_union_use_in_theorem.pf:3.14-3.18: undefined variable: cero 2 | did you intend: zero 3 | 4 | -------------------------------------------------------------------------------- /test/should-error/overload2.pf: -------------------------------------------------------------------------------- 1 | union A { 2 | a 3 | } 4 | 5 | union B { 6 | b 7 | } 8 | 9 | union C { 10 | c 11 | } 12 | 13 | define f : fn A -> bool = λ x { true } 14 | define f : fn B -> bool = λ x { true } 15 | 16 | assert f(a) and f(b) and f(c) -------------------------------------------------------------------------------- /test/should-error/overload2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/overload2.pf:16.26-16.30: could not find a match for function call: 2 | f(c) 3 | argument types: C 4 | overloads: 5 | (fn A -> bool) 6 | (fn B -> bool) 7 | -------------------------------------------------------------------------------- /test/should-error/overload4.pf: -------------------------------------------------------------------------------- 1 | union A { 2 | a 3 | } 4 | 5 | define f : fn A -> bool = λ x { true } 6 | define f : fn A -> bool = λ x { true } 7 | 8 | assert f(a) 9 | -------------------------------------------------------------------------------- /test/should-error/overload4.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/overload4.pf:8.8-8.12: in call to f 2 | ambiguous overloads: 3 | ./test/should-error/overload4.pf:5.12-5.24: (fn A -> bool) 4 | ./test/should-error/overload4.pf:6.12-6.24: (fn A -> bool) 5 | -------------------------------------------------------------------------------- /test/should-error/overload6.pf: -------------------------------------------------------------------------------- 1 | union A { 2 | a 3 | } 4 | 5 | union B { 6 | b 7 | } 8 | 9 | union C { 10 | c 11 | } 12 | 13 | union D { 14 | d 15 | } 16 | 17 | define f : fn A -> bool = λ x { true } 18 | define f : fn B -> bool = λ x { false } 19 | define f : fn C -> bool = λ x { true } 20 | define f : fn D -> bool = λ x { false } 21 | 22 | define g : fn C -> bool = λ x { true } 23 | 24 | define v = a 25 | define v = b 26 | assert not f(v) // this should be the error because v is overloaded but not a function 27 | 28 | define w = c 29 | define w = c 30 | assert f(w) 31 | assert g(w) -------------------------------------------------------------------------------- /test/should-error/overload6.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/overload6.pf:25.1-25.13: the name v is already defined: 2 | ./test/should-error/overload6.pf:24.1-24.13: v : A 3 | Only functions may have multiple definitions with the same name. 4 | -------------------------------------------------------------------------------- /test/should-error/overload_fail.pf: -------------------------------------------------------------------------------- 1 | union Blah { 2 | B(bool) 3 | C(Blah) 4 | D(Blah, Blah) 5 | } 6 | 7 | // Can't overload a union type 8 | define Blah = 9 | fun x:bool { 10 | fun x:bool { 11 | x 12 | } 13 | } -------------------------------------------------------------------------------- /test/should-error/overload_fail.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/overload_fail.pf:10.5-12.6: WARNING: x is already defined 2 | ./test/should-error/overload_fail.pf:8.1-13.4: Cannot overload union names. Blah is already defined as a union 3 | -------------------------------------------------------------------------------- /test/should-error/paren_term.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import List 3 | 4 | recursive sum(List) -> Nat { 5 | sum([]) = 0 6 | sum(node(x, xs)) = x + sum(xs) 7 | } 8 | 9 | print(sum, [1,2,3]) 10 | -------------------------------------------------------------------------------- /test/should-error/paren_term.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/paren_term.pf:9.1-9.10: while parsing 2 | statement ::= "print" term 3 | 4 | ./test/should-error/paren_term.pf:9.10-9.11: expected closing parenthesis ")", not 5 | , 6 | while parsing parenthesized term 7 | term ::= "(" term ")" 8 | 9 | -------------------------------------------------------------------------------- /test/should-error/prefix_operator.pf: -------------------------------------------------------------------------------- 1 | 2 | theorem not_false: not false 3 | proof 4 | ? 5 | end 6 | -------------------------------------------------------------------------------- /test/should-error/prefix_operator.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/prefix_operator.pf:4.3-4.4: incomplete proof 2 | Goal: 3 | not false 4 | Advice: 5 | Prove this if-then formula with: 6 | assume label: false 7 | followed by a proof of: 8 | false 9 | -------------------------------------------------------------------------------- /test/should-error/print_precedence_assoc.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: all x:Nat, y:Nat, z:Nat. x + (y + z) + ℕ0 = x + y + z 4 | proof 5 | ? 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/print_precedence_assoc.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/print_precedence_assoc.pf:5.3-5.4: incomplete proof 2 | Goal: 3 | (all x:Nat, y:Nat, z:Nat. (x + (y + z)) + ℕ0 = (x + y) + z) 4 | Advice: 5 | Prove this "all" formula with: 6 | arbitrary x:Nat, y:Nat, z:Nat 7 | followed by a proof of: 8 | (x + (y + z)) + ℕ0 = (x + y) + z 9 | 10 | Alternatively, you can try induction with: 11 | induction Nat 12 | case zero { 13 | ? 14 | } 15 | case suc(N1) assume IH1: (all y:Nat, z:Nat. (N1 + (y + z)) + ℕ0 = (N1 + y) + z) { 16 | ? 17 | } 18 | 19 | -------------------------------------------------------------------------------- /test/should-error/private_opaque.pf: -------------------------------------------------------------------------------- 1 | private opaque define X: bool = true -------------------------------------------------------------------------------- /test/should-error/private_opaque.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/private_opaque.pf:1.9-1.15: expected a statement, not 2 | opaque 3 | -------------------------------------------------------------------------------- /test/should-error/recursive_clause_name_mismatch.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | recursive f(Nat) -> Nat { 4 | g(0) = 0 5 | g(suc(n)) = f(n) 6 | } 7 | -------------------------------------------------------------------------------- /test/should-error/recursive_clause_name_mismatch.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/recursive_clause_name_mismatch.pf:4.3-4.4: expected function name "f", not "g" 2 | -------------------------------------------------------------------------------- /test/should-error/recursive_import_one.pf: -------------------------------------------------------------------------------- 1 | import recursive_import_two 2 | 3 | fun f(x : bool) { 4 | g(x) 5 | } 6 | -------------------------------------------------------------------------------- /test/should-error/recursive_import_one.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/recursive_import_one.pf:1.1-1.28: could not find a file for import: recursive_import_two 2 | -------------------------------------------------------------------------------- /test/should-error/recursive_import_two.pf: -------------------------------------------------------------------------------- 1 | import recursive_import_one 2 | 3 | fun g(x : bool) { 4 | f(x) 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/should-error/recursive_import_two.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/recursive_import_two.pf:1.1-1.28: could not find a file for import: recursive_import_one 2 | -------------------------------------------------------------------------------- /test/should-error/reduce_all.pf: -------------------------------------------------------------------------------- 1 | union A { a b } 2 | 3 | fun blah(n : A) { 4 | if n = a then b else a 5 | } 6 | 7 | theorem asdf : all x : A. 8 | blah(blah(x)) = x 9 | proof 10 | suffices ? by evaluate 11 | ? 12 | end -------------------------------------------------------------------------------- /test/should-error/reduce_all.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/reduce_all.pf:10.3-10.25: 2 | suffices to prove: 3 | (all x:A. (if (if x = a then b else a) = a then b else a) = x) 4 | ./test/should-error/reduce_all.pf:11.3-11.4: incomplete proof 5 | Goal: 6 | (all x:A. (if (if x = a then b else a) = a then b else a) = x) 7 | Advice: 8 | Prove this "all" formula with: 9 | arbitrary x:A 10 | followed by a proof of: 11 | (if (if x = a then b else a) = a then b else a) = x 12 | 13 | Alternatively, you can try induction with: 14 | induction A 15 | case a { 16 | ? 17 | } 18 | case b { 19 | ? 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/should-error/reflexive_not_equality.pf: -------------------------------------------------------------------------------- 1 | theorem T: true 2 | proof 3 | have: true = true by reflexive 4 | reflexive 5 | end 6 | -------------------------------------------------------------------------------- /test/should-error/reflexive_not_equality.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/reflexive_not_equality.pf:4.3-4.12: reflexive proves an equality, not 2 | true 3 | Givens: 4 | _: true = true 5 | -------------------------------------------------------------------------------- /test/should-error/remains_to_prove.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: all x:Nat. ℕ0 + (ℕ0 + x) = x 4 | proof 5 | arbitrary x:Nat 6 | replace zero_add 7 | end 8 | -------------------------------------------------------------------------------- /test/should-error/remains_to_prove.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/remains_to_prove.pf:7.1-7.4: incomplete proof 2 | Goal: 3 | ℕ0 + x = x 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | -------------------------------------------------------------------------------- /test/should-error/remains_to_prove_def.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: all x:Nat. ℕ0 + (x + ℕ0) = x 4 | proof 5 | arbitrary x:Nat 6 | expand operator+ 7 | end 8 | -------------------------------------------------------------------------------- /test/should-error/remains_to_prove_def.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/remains_to_prove_def.pf:7.1-7.4: incomplete proof 2 | Goal: 3 | x + ℕ0 = x 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | -------------------------------------------------------------------------------- /test/should-error/replace_match_failure.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: all x:Nat, y:Nat, z:Nat. if suc(x) = y then z = y 4 | proof 5 | arbitrary x:Nat, y:Nat, z:Nat 6 | assume prem: suc(x) = y 7 | replace prem. 8 | end 9 | 10 | 11 | -------------------------------------------------------------------------------- /test/should-error/replace_match_failure.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/replace_match_failure.pf:7.3-7.15: 2 | could not find any matches for 3 | suc(x) 4 | in 5 | z = y 6 | while trying to replace using the below equation, left to right 7 | suc(x) = y 8 | -------------------------------------------------------------------------------- /test/should-error/shadow_warn1.pf: -------------------------------------------------------------------------------- 1 | union Blah { 2 | B(bool) 3 | C(Blah) 4 | D(Blah, Blah) 5 | } 6 | 7 | // Function binding 8 | define C = 9 | fun x:bool { 10 | fun x:bool { 11 | x 12 | } 13 | } 14 | 15 | assert C(true)(false) 16 | -------------------------------------------------------------------------------- /test/should-error/shadow_warn1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/shadow_warn1.pf:10.5-12.6: WARNING: x is already defined 2 | ./test/should-error/shadow_warn1.pf:15.1-15.22: assertion failed: C(true)(false) 3 | -------------------------------------------------------------------------------- /test/should-error/shadow_warn2.pf: -------------------------------------------------------------------------------- 1 | // This should trigger a lot of warnings for already in use variables 2 | // The assert false at the end is so that we can actually look at the output 3 | // - Calvin 4 | 5 | union Blah { 6 | B(bool) 7 | C(Blah) 8 | D(Blah, Blah) 9 | } 10 | 11 | // Function binding 12 | define C = 13 | fun x:bool { 14 | fun x:bool { 15 | x 16 | } 17 | } 18 | 19 | define True = true 20 | 21 | // In forall, some, arbitrary, assumes of cases, have, define in proof 22 | theorem blah : all C : bool. some D : bool. True 23 | proof 24 | arbitrary B : bool 25 | switch B { 26 | case true assume prop_t { 27 | choose true 28 | switch B { 29 | case true assume prop_t { 30 | expand True. 31 | } 32 | case false assume prop_f { 33 | have prop_t : true by . 34 | expand True 35 | prop_t 36 | } 37 | } 38 | } 39 | case false assume blah' { 40 | define blah' = True 41 | choose false 42 | ? 43 | } 44 | } 45 | end 46 | 47 | assert false 48 | -------------------------------------------------------------------------------- /test/should-error/shadow_warn2.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/shadow_warn2.pf:14.5-16.6: WARNING: x is already defined 2 | ./test/should-error/shadow_warn2.pf:22.16-22.49: WARNING: C is already defined 3 | ./test/should-error/shadow_warn2.pf:22.30-22.49: WARNING: D is already defined 4 | ./test/should-error/shadow_warn2.pf:24.3-24.21: WARNING: B is already defined 5 | ./test/should-error/shadow_warn2.pf:29.9-31.10: WARNING: prop_t is already defined 6 | ./test/should-error/shadow_warn2.pf:33.11-33.34: WARNING: prop_t is already defined 7 | ./test/should-error/shadow_warn2.pf:40.7-40.26: WARNING: blah' is already defined 8 | ./test/should-error/shadow_warn2.pf:42.7-42.8: incomplete proof 9 | Goal: 10 | blah' 11 | 12 | 13 | Givens: 14 | blah': B = false 15 | -------------------------------------------------------------------------------- /test/should-error/shadow_warn3.pf: -------------------------------------------------------------------------------- 1 | // type bindings warning 2 | define blah : fn T -> (fn T -> T) 3 | = generic T { 4 | fun x : T { 5 | generic T { 6 | fun y : T { 7 | x 8 | } 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /test/should-error/shadow_warn3.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/shadow_warn3.pf:2.29-2.42: WARNING: T is already defined 2 | ./test/should-error/shadow_warn3.pf:5.9-9.10: WARNING: T is already defined 3 | ./test/should-error/shadow_warn3.pf:7.13-7.14: expected a term of type T 4 | but got term x of type T 5 | -------------------------------------------------------------------------------- /test/should-error/shadow_warn4.pf: -------------------------------------------------------------------------------- 1 | union Blah { 2 | B(bool) 3 | C(Blah) 4 | D(Blah, Blah) 5 | } 6 | 7 | 8 | // Switch case in functions 9 | recursive dist(Blah) -> bool { 10 | dist(B(b)) = b 11 | dist(C(b)) = dist(b) 12 | dist(D(b1, b2)) = 13 | switch b1 { 14 | case B(b) { if b then b else dist(b2) } 15 | case C(b) { dist(b1) } 16 | case D(b1, b2) { dist(b2) } 17 | } 18 | } -------------------------------------------------------------------------------- /test/should-error/shadow_warn4.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/shadow_warn4.pf:16.9-16.36: WARNING: b1 is already defined 2 | ./test/should-error/shadow_warn4.pf:16.9-16.36: WARNING: b2 is already defined 3 | ./test/should-error/shadow_warn4.pf:16.26-16.34: ill-formed recursive call 4 | expected first argument to be b1 or b2, not b2 5 | -------------------------------------------------------------------------------- /test/should-error/suffices_evaluate.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem test : all x : Nat. ℕ2 + x + ℕ1 + ℕ1 + ℕ2 + x + ℕ1 ∸ ℕ2 ∸ ℕ2 = ℕ3 + x + ℕ2 + ℕ1 + x ∸ ℕ2 + ℕ1 4 | proof 5 | arbitrary x : Nat 6 | suffices ? by evaluate 7 | ? 8 | end 9 | -------------------------------------------------------------------------------- /test/should-error/suffices_evaluate.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/suffices_evaluate.pf:6.3-6.25: 2 | suffices to prove: 3 | ((x + suc(suc(suc(suc(x + ℕ1))))) ∸ ℕ0) ∸ ℕ2 = suc(x + suc(suc(suc(x + ℕ1)))) 4 | ./test/should-error/suffices_evaluate.pf:7.3-7.4: incomplete proof 5 | Goal: 6 | ((x + suc(suc(suc(suc(x + ℕ1))))) ∸ ℕ0) ∸ ℕ2 = suc(x + suc(suc(suc(x + ℕ1)))) 7 | Advice: 8 | To prove this equality, one of these statements might help: 9 | expand 10 | replace 11 | equations 12 | 13 | -------------------------------------------------------------------------------- /test/should-error/suffices_implies_hole.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool. if P and (if P then Q) then Q 2 | proof 3 | arbitrary P:bool, Q:bool 4 | assume prem: (P and (if P then Q)) 5 | have pq: if P then Q by prem 6 | suffices ? by pq 7 | ? 8 | end 9 | -------------------------------------------------------------------------------- /test/should-error/suffices_implies_hole.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/suffices_implies_hole.pf:6.12-6.13: 2 | suffices to prove: 3 | P 4 | ./test/should-error/suffices_implies_hole.pf:7.3-7.4: incomplete proof 5 | Goal: 6 | P 7 | 8 | 9 | Givens: 10 | pq: (if P then Q), 11 | prem: (P and (if P then Q)) 12 | -------------------------------------------------------------------------------- /test/should-error/suffices_misspell.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. if (if P then Q) and (if Q then R) and P then R 2 | proof 3 | arbitrary P:bool, Q:bool, R:bool 4 | suppose prem 5 | sufices Q by prem 6 | suffices P by prem 7 | prem 8 | end 9 | -------------------------------------------------------------------------------- /test/should-error/suffices_misspell.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/suffices_misspell.pf:1.1-4.15: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/should-error/suffices_misspell.pf:5.3-5.10: expected a proof. 4 | Did you mean "suffices" instead of "sufices"? 5 | -------------------------------------------------------------------------------- /test/should-error/suffices_omitted.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | theorem __: all x:UInt. length([x]) = 1 5 | proof 6 | arbitrary x:Nat 7 | expand 2*length 8 | uint_add_zero[1] 9 | end 10 | -------------------------------------------------------------------------------- /test/should-error/suffices_omitted.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/suffices_omitted.pf:4.1-4.8: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/should-error/suffices_omitted.pf:4.9-4.11: expected name of theorem, not: 4 | __ 5 | -------------------------------------------------------------------------------- /test/should-error/sum_append.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import List 3 | 4 | recursive sum(List) -> Nat { 5 | sum([]) = ℕ0 6 | sum(node(x,ls)) = x + sum(ls) 7 | } 8 | 9 | assert sum([ℕ1, ℕ2, ℕ3]) = sum(reverse([ℕ1, ℕ2, ℕ3])) 10 | 11 | /* 12 | sum([1,2,3] ++ [4,5,6]) 13 | = sum([1,2,3,4,5,6]) 14 | = sum([1,2,3]) + sum([4,5,6]) 15 | */ 16 | 17 | 18 | theorem sum_append: all ls1 : List, ls2 : List. 19 | sum(ls1 ++ ls2) = sum(ls1) + sum(ls2) 20 | proof 21 | induction List 22 | case [] { 23 | arbitrary ls2:List 24 | conclude sum(@[] ++ ls2) = sum(@[]) + sum(ls2) 25 | by expand operator++ | sum | operator+. 26 | } 27 | case node(x, ls1) suppose IH { 28 | arbitrary ls2:List 29 | equations 30 | sum(node(x, ls1) ++ ls2) 31 | = sum(node(x, ls1 ++ ls2)) 32 | by expand operator++. 33 | ... = x + sum(ls1 ++ ls2) 34 | by expand sum. 35 | ... = x + (sum(ls1) ++ sum(ls2)) 36 | by replace IH[ls2]. 37 | ... = (x + sum(ls1)) + sum(ls2) 38 | by symmetric add_assoc[x,sum(ls1),sum(ls2)] 39 | ... = #sum(node(x, ls1))# + sum(ls2) 40 | by expand sum. 41 | } 42 | end 43 | -------------------------------------------------------------------------------- /test/should-error/sum_append.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/sum_append.pf:35.16-35.36: expected type Nat 2 | but the call sum(ls1) ++ sum(ls2) 3 | has return type List 4 | 5 | inferred type arguments: 6 | -------------------------------------------------------------------------------- /test/should-error/sum_def.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import List 3 | 4 | recursive sum(List) -> Nat { 5 | sum([]) = ℕ0 6 | sum(node(x,ls)) = x + sum(ls) 7 | } 8 | 9 | theorem sum_reverse: 10 | all ls : List. sum(ls) = sum(reverse(ls)) 11 | proof 12 | induction List 13 | case [] { 14 | expand sum 15 | ? 16 | } 17 | case node(x, ls) suppose IH { 18 | ? 19 | } 20 | end 21 | -------------------------------------------------------------------------------- /test/should-error/sum_def.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/sum_def.pf:15.5-15.6: incomplete proof 2 | Goal: 3 | ℕ0 = sum(reverse(@[])) 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | -------------------------------------------------------------------------------- /test/should-error/sum_foldr.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | 4 | recursive sum(List) -> Nat { 5 | sum(empty) = ℕ0 6 | sum(node(n, ns)) = n + sum(ns) 7 | } 8 | 9 | 10 | theorem foldr_eq_sum : all ls : List. sum(ls) = foldr(ls, ℕ0, operator+) 11 | proof 12 | induction List 13 | case empty { 14 | expand sum 15 | ? 16 | } 17 | case node(a, d) { 18 | ? 19 | } 20 | end 21 | -------------------------------------------------------------------------------- /test/should-error/sum_foldr.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/sum_foldr.pf:15.5-15.6: incomplete proof 2 | Goal: 3 | ℕ0 = foldr(@[], ℕ0, operator +) 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | -------------------------------------------------------------------------------- /test/should-error/sum_foldr_switch.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | 4 | recursive sum(List) -> Nat { 5 | sum(empty) = ℕ0 6 | sum(node(n, ns)) = n + sum(ns) 7 | } 8 | 9 | 10 | theorem foldr_eq_sum : all ls : List. sum(ls) = foldr(ls, ℕ0, operator+) 11 | proof 12 | arbitrary ls : List 13 | switch ls { 14 | case empty { 15 | expand sum 16 | ? 17 | } 18 | case node(a, d) { 19 | ? 20 | } 21 | } 22 | end 23 | -------------------------------------------------------------------------------- /test/should-error/sum_foldr_switch.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/sum_foldr_switch.pf:16.7-16.8: incomplete proof 2 | Goal: 3 | ℕ0 = foldr(@[], ℕ0, operator +) 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | Givens: 11 | _: ls = [] 12 | -------------------------------------------------------------------------------- /test/should-error/switch_case_close.pf: -------------------------------------------------------------------------------- 1 | union Bit { 2 | zero 3 | one 4 | } 5 | 6 | define b = zero 7 | 8 | assert switch b { 9 | case zero { true 10 | case one { true } 11 | } 12 | -------------------------------------------------------------------------------- /test/should-error/switch_case_close.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/switch_case_close.pf:8.1-9.26: while parsing assert 2 | statement ::= "assert" formula 3 | 4 | ./test/should-error/switch_case_close.pf:9.10-10.14: while parsing 5 | switch_case ::= "case" pattern "{" term "}" 6 | ./test/should-error/switch_case_close.pf:10.10-10.14: expected a "}" after body of case, not 7 | "case" 8 | -------------------------------------------------------------------------------- /test/should-error/switch_case_empty.pf: -------------------------------------------------------------------------------- 1 | union Bit { 2 | zero 3 | one 4 | } 5 | 6 | define b = zero 7 | 8 | assert switch b { 9 | case zero { } 10 | case one { true } 11 | } 12 | -------------------------------------------------------------------------------- /test/should-error/switch_case_empty.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/switch_case_empty.pf:8.1-9.21: while parsing assert 2 | statement ::= "assert" formula 3 | 4 | ./test/should-error/switch_case_empty.pf:9.10-9.23: while parsing 5 | switch_case ::= "case" pattern "{" term "}" 6 | ./test/should-error/switch_case_empty.pf:9.22-9.23: expected a term, not 7 | "}" 8 | -------------------------------------------------------------------------------- /test/should-error/switch_case_open.pf: -------------------------------------------------------------------------------- 1 | union Bit { 2 | zero 3 | one 4 | } 5 | 6 | define b = zero 7 | 8 | assert switch b { 9 | case zero true 10 | case one { true } 11 | } 12 | -------------------------------------------------------------------------------- /test/should-error/switch_case_open.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/switch_case_open.pf:8.1-9.19: while parsing assert 2 | statement ::= "assert" formula 3 | 4 | ./test/should-error/switch_case_open.pf:9.10-9.24: while parsing 5 | switch_case ::= "case" pattern "{" term "}" 6 | ./test/should-error/switch_case_open.pf:9.20-9.24: expected a "{" after pattern of case, not 7 | "true" 8 | -------------------------------------------------------------------------------- /test/should-error/switch_case_pattern.pf: -------------------------------------------------------------------------------- 1 | union Bit { 2 | zero 3 | one 4 | } 5 | 6 | define b = zero 7 | 8 | assert switch b { 9 | case zero { true } 10 | case { true } 11 | } 12 | -------------------------------------------------------------------------------- /test/should-error/switch_case_pattern.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/switch_case_pattern.pf:8.1-10.14: while parsing assert 2 | statement ::= "assert" formula 3 | 4 | ./test/should-error/switch_case_pattern.pf:10.10-10.16: while parsing 5 | switch_case ::= "case" pattern "{" term "}" 6 | ./test/should-error/switch_case_pattern.pf:10.15-10.16: expected a pattern, not 7 | "{" 8 | -------------------------------------------------------------------------------- /test/should-error/switch_term_error.pf: -------------------------------------------------------------------------------- 1 | union Bit { 2 | zero 3 | one 4 | } 5 | 6 | define b = zero 7 | 8 | assert switch b { 9 | case zero { true } 10 | } -------------------------------------------------------------------------------- /test/should-error/switch_term_error.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/switch_term_error.pf:8.8-10.9: missing a case for: 2 | one 3 | -------------------------------------------------------------------------------- /test/should-error/term_inst_foldr.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | 4 | recursive sum(List) -> Nat { 5 | sum(empty) = ℕ0 6 | sum(node(n, ns)) = n + sum(ns) 7 | } 8 | 9 | 10 | theorem foldr_eq_sum : all ls : List. sum(ls) = foldr(ls, ℕ0, operator+) 11 | proof 12 | induction List 13 | case empty { 14 | expand sum 15 | ? 16 | } 17 | case node(a, d) { 18 | ? 19 | } 20 | end 21 | -------------------------------------------------------------------------------- /test/should-error/term_inst_foldr.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/term_inst_foldr.pf:15.5-15.6: incomplete proof 2 | Goal: 3 | ℕ0 = foldr(@[], ℕ0, operator +) 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | -------------------------------------------------------------------------------- /test/should-error/term_inst_length_node.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | theorem l1 : length(node(1, empty)) = 1 5 | proof 6 | expand length 7 | ? 8 | end 9 | -------------------------------------------------------------------------------- /test/should-error/term_inst_length_node.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/term_inst_length_node.pf:7.3-7.4: incomplete proof 2 | Goal: 3 | 1 + length(@[]) = 1 4 | Advice: 5 | To prove this equality, one of these statements might help: 6 | expand 7 | replace 8 | equations 9 | 10 | -------------------------------------------------------------------------------- /test/should-error/theorem_and5.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. if P and Q then R 2 | proof 3 | arbitrary P:bool, Q:bool, R:bool 4 | suppose prem 5 | prem 6 | end -------------------------------------------------------------------------------- /test/should-error/theorem_and5.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_and5.pf:5.3-5.7: 2 | Could not prove that 3 | (P and Q) 4 | implies 5 | R 6 | because we could not prove at least one of 7 | P implies R 8 | Q implies R 9 | -------------------------------------------------------------------------------- /test/should-error/theorem_and6.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. if P then Q and R 2 | proof 3 | arbitrary P:bool, Q:bool, R:bool 4 | suppose prem 5 | prem 6 | end -------------------------------------------------------------------------------- /test/should-error/theorem_and6.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_and6.pf:5.3-5.7: 2 | Could not prove that 3 | P 4 | implies 5 | Q 6 | 7 | While trying to prove that 8 | P 9 | implies 10 | (Q and R) 11 | -------------------------------------------------------------------------------- /test/should-error/theorem_implies5.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. if (if P then Q) then (if P then R) 2 | proof 3 | arbitrary P:bool, Q:bool, R:bool 4 | suppose prem 5 | prem 6 | end 7 | -------------------------------------------------------------------------------- /test/should-error/theorem_implies5.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_implies5.pf:5.3-5.7: 2 | Could not prove that 3 | Q 4 | implies 5 | R 6 | 7 | While trying to prove that 8 | (if P then Q) 9 | implies 10 | (if P then R) 11 | -------------------------------------------------------------------------------- /test/should-error/theorem_implies6.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. if (if P then R) then (if Q then R) 2 | proof 3 | arbitrary P:bool, Q:bool, R:bool 4 | suppose prem 5 | prem 6 | end 7 | theorem T: all P:bool, Q:bool, R:bool. if (if P then R) then (if Q then R) 8 | proof 9 | arbitrary P:bool, Q:bool, R:bool 10 | suppose prem 11 | prem 12 | end 13 | -------------------------------------------------------------------------------- /test/should-error/theorem_implies6.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_implies6.pf:7.1-12.4: theorem names may not be overloaded 2 | -------------------------------------------------------------------------------- /test/should-error/theorem_implies8.pf: -------------------------------------------------------------------------------- 1 | theorem T1: if true 2 | proof 3 | suppose _ 4 | . 5 | end 6 | -------------------------------------------------------------------------------- /test/should-error/theorem_implies8.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_implies8.pf:1.1-1.20: while parsing 2 | proof_stmt ::= "theorem" identifier ":" formula "proof" proof "end" 3 | ./test/should-error/theorem_implies8.pf:2.1-2.6: expected keyword "then" after premise of "if" formula, not 4 | proof 5 | while parsing 6 | formula ::= "if" formula "then" formula 7 | -------------------------------------------------------------------------------- /test/should-error/theorem_implies_7.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. 2 | if (P and Q and R) then ((if P then Q) and (if Q then R)) 3 | proof 4 | arbitrary P:bool, Q:bool, R:bool 5 | suppose prem 6 | have ptq : if P then Q by suppose P' prem 7 | have qtr : if Q then R by suppose Q' prem 8 | ptq, qtr 9 | end 10 | 11 | 12 | theorem t2: all P:bool, Q:bool, R:bool. 13 | if (P and Q and R) then P and R 14 | proof 15 | arbitrary P:bool, Q:bool, R:bool 16 | suppose prem : P and Q and R 17 | have step : (if P then Q) and (if Q then R) by apply T[P, Q, R] to prem 18 | apply step to prem 19 | end 20 | -------------------------------------------------------------------------------- /test/should-error/theorem_implies_7.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_implies_7.pf:18.3-18.21: 2 | Could not prove that 3 | (Q and R) 4 | implies 5 | P 6 | because we could not prove at least one of 7 | Q implies P 8 | R implies P 9 | 10 | While trying to prove that 11 | (Q and R) 12 | implies 13 | (P and R) 14 | -------------------------------------------------------------------------------- /test/should-error/theorem_misspelled.pf: -------------------------------------------------------------------------------- 1 | therem T: true 2 | proof 3 | . 4 | end 5 | -------------------------------------------------------------------------------- /test/should-error/theorem_misspelled.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_misspelled.pf:1.1-1.7: did you mean "theorem" instead of "therem"? 2 | -------------------------------------------------------------------------------- /test/should-error/theorem_or3.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool. if P or P then Q 2 | proof 3 | arbitrary P:bool, Q:bool 4 | suppose prem 5 | conclude Q by prem 6 | end -------------------------------------------------------------------------------- /test/should-error/theorem_or3.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_or3.pf:5.17-5.21: 2 | Could not prove that 3 | P 4 | implies 5 | Q 6 | 7 | While trying to prove that 8 | (P or P) 9 | implies 10 | Q 11 | -------------------------------------------------------------------------------- /test/should-error/theorem_or4.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. if P then Q or R 2 | proof 3 | arbitrary P:bool, Q:bool, R:bool 4 | suppose prem 5 | prem 6 | end -------------------------------------------------------------------------------- /test/should-error/theorem_or4.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_or4.pf:5.3-5.7: 2 | Could not prove that 3 | P 4 | implies 5 | (Q or R) 6 | because we could not prove at least one of 7 | P implies Q 8 | P implies R 9 | -------------------------------------------------------------------------------- /test/should-error/theorem_true_error.pf: -------------------------------------------------------------------------------- 1 | // error expected because true does not imply false 2 | theorem true_is_false: false 3 | proof 4 | . 5 | end 6 | -------------------------------------------------------------------------------- /test/should-error/theorem_true_error.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/theorem_true_error.pf:4.3-4.4: 2 | Could not prove that 3 | true 4 | implies 5 | false 6 | -------------------------------------------------------------------------------- /test/should-error/transitive1.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | define one = ℕ1 4 | 5 | theorem T: ℕ1 = one 6 | proof 7 | have: one = one by . 8 | conclude ℕ1 = one by (transitive (recall one = one) (recall one = one)) 9 | end 10 | -------------------------------------------------------------------------------- /test/should-error/transitive1.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/transitive1.pf:8.25-8.35: for transitive, from proofs of 2 | one = one 3 | and 4 | one = one 5 | the transitive rule concludes 6 | one = one 7 | but that does not match the goal 8 | ℕ1 = one 9 | 10 | Givens: 11 | _: one = one 12 | -------------------------------------------------------------------------------- /test/should-error/unclosed_comment.pf: -------------------------------------------------------------------------------- 1 | /* 2 | Oops, my bad! -------------------------------------------------------------------------------- /test/should-error/unclosed_comment.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/unclosed_comment.pf:1.1-1.2: expected a statement, not '/*', did you forget to close a comment? 2 | -------------------------------------------------------------------------------- /test/should-error/union_bad_constructor.pf: -------------------------------------------------------------------------------- 1 | union Tree { 2 | empty(bool) 3 | node(Tree Tree) 4 | } 5 | -------------------------------------------------------------------------------- /test/should-error/union_bad_constructor.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/union_bad_constructor.pf:1.1-3.12: while parsing 2 | statement ::= "union" identifier type_params_opt "{" constructor* "}" 3 | 4 | ./test/should-error/union_bad_constructor.pf:3.3-3.12: while parsing 5 | constructor ::= identifier | identifier "(" type_list ")" 6 | ./test/should-error/union_bad_constructor.pf:3.3-3.12: missing closing parenthesis 7 | -------------------------------------------------------------------------------- /test/should-error/union_missing_name.pf: -------------------------------------------------------------------------------- 1 | union { 2 | empty(bool) 3 | node(Tree, Nat,Tree) 4 | } 5 | -------------------------------------------------------------------------------- /test/should-error/union_missing_name.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/union_missing_name.pf:1.1-1.6: while parsing 2 | statement ::= "union" identifier type_params_opt "{" constructor* "}" 3 | 4 | ./test/should-error/union_missing_name.pf:1.7-1.8: expected an identifier, not 5 | "{" 6 | -------------------------------------------------------------------------------- /test/should-error/use_private_define.pf: -------------------------------------------------------------------------------- 1 | import Log 2 | 3 | assert log_one = log_one -------------------------------------------------------------------------------- /test/should-error/use_private_define.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/use_private_define.pf:3.8-3.15: undefined variable: log_one 2 | -------------------------------------------------------------------------------- /test/should-error/use_private_function.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | assert div2_aux(4) = 2 4 | -------------------------------------------------------------------------------- /test/should-error/use_private_function.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/use_private_function.pf:3.8-3.16: undefined variable: div2_aux 2 | -------------------------------------------------------------------------------- /test/should-error/use_private_union.pf: -------------------------------------------------------------------------------- 1 | import Private 2 | 3 | assert positive = positive 4 | -------------------------------------------------------------------------------- /test/should-error/use_private_union.pf.err: -------------------------------------------------------------------------------- 1 | ./test/should-error/use_private_union.pf:3.8-3.16: undefined variable: positive 2 | -------------------------------------------------------------------------------- /test/should-validate/ImportTests.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import Nat 3 | 4 | private union Bit { 5 | High 6 | Low 7 | } 8 | 9 | 10 | private recursive add_one_all(List) -> List { 11 | add_one_all([]) = [] 12 | add_one_all(node(x, xs)) = node(suc(x), add_one_all(xs)) 13 | } 14 | 15 | define f : fn Bit -> Bit = fun b { b } 16 | 17 | assert f(High) = High 18 | assert f(Low) = Low 19 | 20 | union OneTwo { 21 | One 22 | Two 23 | } 24 | 25 | opaque define id_one_two : fn OneTwo -> OneTwo = fun b { b } 26 | 27 | theorem id_one_two_works: all b:OneTwo. id_one_two(b) = b 28 | proof 29 | arbitrary b:OneTwo 30 | expand id_one_two. 31 | end 32 | -------------------------------------------------------------------------------- /test/should-validate/IntTests.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import Int 3 | 4 | assert +1 ≤ +1 5 | assert +1 ≤ +2 6 | assert -1 ≤ -1 7 | assert -2 ≤ -1 8 | assert +0 ≤ +1 9 | assert -1 ≤ +0 10 | -------------------------------------------------------------------------------- /test/should-validate/ListTests.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import UInt 3 | import List 4 | import Maps 5 | 6 | private define L1 = node(1, node(2, empty)) 7 | private define L2 = node(3, node(4, node(5, empty))) 8 | private define L3 : List = node(1, node(2, node(3, node(4, node(5, empty))))) 9 | 10 | assert length(L1) = 2 11 | assert length(L3) = 5 12 | assert L1 ++ L2 = L3 13 | assert reverse(L1) = node(2, node(1, empty)) 14 | assert reverse(L2) = node(5, node(4, node(3, empty))) 15 | assert length(L1 ++ L2) = length(L1) + length(L2) 16 | 17 | assert map(L1, (fun x : UInt { 1 + x })) = node(2, node(3, empty)) 18 | 19 | assert foldr(L1, 0, λa,b{ a + b }) = 3 20 | assert foldr(L1, @empty, λx,ls{ node(x,ls) }) = L1 21 | 22 | assert foldl(L1, 0, λa,b{ a + b }) = 3 23 | assert foldl(L1, @empty, λls,x{ node(x,ls) }) = node(2,node(1,empty)) 24 | 25 | assert down_from(ℕ2) = node(ℕ1, node(ℕ0, empty)) 26 | 27 | assert up_to(ℕ2) = node(ℕ0, node(ℕ1, empty)) 28 | assert up_to(ℕ3) = node(ℕ0, node(ℕ1, node(ℕ2, empty))) 29 | 30 | assert range(ℕ0, ℕ0) = empty 31 | assert range(ℕ0, ℕ1) = [ℕ0] 32 | assert range(ℕ0, ℕ2) = node(ℕ0, node(ℕ1, empty)) 33 | assert range(ℕ1, ℕ3) = node(ℕ1, node(ℕ2, empty)) 34 | assert range(ℕ2, ℕ5) = node(ℕ2, node(ℕ3, node(ℕ4, empty))) 35 | 36 | assert interval(ℕ0, ℕ0) = empty 37 | assert interval(ℕ1, ℕ0) = node(ℕ0, empty) 38 | assert interval(ℕ2, ℕ0) = node(ℕ0, node(ℕ1, empty)) 39 | assert interval(ℕ3, ℕ0) = node(ℕ0, node(ℕ1, node(ℕ2, empty))) 40 | 41 | assert interval(ℕ0, ℕ3) = empty 42 | assert interval(ℕ1, ℕ3) = node(ℕ3, empty) 43 | assert interval(ℕ2, ℕ3) = node(ℕ3, node(ℕ4, empty)) 44 | assert interval(ℕ3, ℕ3) = node(ℕ3, node(ℕ4, node(ℕ5, empty))) 45 | 46 | assert (node(1, empty) ++ node(2, empty)) ++ node(3, empty) 47 | = node(1, empty) ++ (node(2, empty) ++ node(3, empty)) 48 | 49 | define id_nat : fn UInt -> UInt = λx{x} 50 | 51 | assert (id_nat .o. id_nat)(0) = 0 52 | 53 | assert length(@empty) = 0 54 | assert length(node(42, empty)) = 1 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /test/should-validate/LogTests.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import Log 3 | 4 | define log_one = log(ℕ1) 5 | define log_two = log(ℕ2) 6 | define log_three = log(ℕ3) 7 | define log_four = log(ℕ4) 8 | define log_five = log(ℕ5) 9 | define log_eight = log(ℕ8) 10 | 11 | assert log_one = ℕ0 12 | assert log_two = ℕ1 13 | assert log_three = ℕ2 14 | assert log_four = ℕ2 15 | assert log_five = ℕ3 16 | assert log_eight = ℕ3 17 | -------------------------------------------------------------------------------- /test/should-validate/NatTests.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import Option 3 | 4 | assert ℕ0/ℕ2 = ℕ0 5 | assert ℕ1/ℕ2 = ℕ0 6 | assert ℕ2/ℕ2 = ℕ1 7 | assert ℕ3/ℕ2 = ℕ1 8 | assert ℕ4/ℕ2 = ℕ2 9 | assert ℕ5/ℕ2 = ℕ2 10 | assert ℕ6/ℕ2 = ℕ3 11 | 12 | assert ℕ5 / ℕ3 = ℕ1 13 | assert ℕ6 / ℕ3 = ℕ2 14 | 15 | assert ℕ2 / ℕ1 = ℕ2 16 | assert ℕ4 / ℕ2 = ℕ2 17 | assert ℕ5 / ℕ2 = ℕ2 18 | assert ℕ6 / ℕ2 = ℕ3 19 | assert ℕ3 / ℕ3 = ℕ1 20 | assert ℕ9 / ℕ3 = ℕ3 21 | assert ℕ10 / ℕ3 = ℕ3 22 | 23 | assert pow2(ℕ0) = ℕ1 24 | assert pow2(ℕ1) = ℕ2 25 | assert pow2(ℕ2) = ℕ4 26 | assert pow2(ℕ3) = ℕ8 27 | assert pow2(ℕ4) = ℕ16 28 | 29 | 30 | assert ℕ0 ^ ℕ0 = ℕ1 31 | assert ℕ0 ^ ℕ5 = ℕ0 32 | assert ℕ2 ^ ℕ3 = ℕ8 33 | assert ℕ3 ^ ℕ3 = ℕ27 34 | assert ℕ2 ^ ℕ2 * ℕ3 = ℕ12 35 | assert ℕ2 ^ ℕ2 + ℕ2 = ℕ6 36 | assert ℕ1 + ℕ2 ^ ℕ2 + ℕ1 = ℕ6 37 | -------------------------------------------------------------------------------- /test/should-validate/after.pf: -------------------------------------------------------------------------------- 1 | import Option 2 | 3 | union Nat { 4 | zero 5 | suc(Nat) 6 | } 7 | 8 | union Pos { 9 | one 10 | succ(Pos) 11 | } 12 | 13 | recursive nat2pos(Nat) -> Option { 14 | nat2pos(0) = none 15 | nat2pos(suc(n')) = 16 | switch nat2pos(n') { 17 | case none { 18 | just(one) 19 | } 20 | case just(p) { 21 | just(succ(p)) 22 | } 23 | } 24 | } 25 | 26 | recursive div_helper(Nat,Nat,Pos,Pos) -> Nat { 27 | div_helper(0, k, m, j) = k 28 | div_helper(suc(n'), k, m, j) = 29 | switch j { 30 | case one { 31 | div_helper(n', suc(k), m, m) 32 | } 33 | case succ(j') { 34 | div_helper(n', k, m, j') 35 | } 36 | } 37 | } 38 | 39 | fun operator /(n : Nat, m : Pos) { 40 | switch n { 41 | case 0 { ℕ0 } 42 | case suc(n') { div_helper(suc(n'), ℕ0, m, m) } 43 | } 44 | } 45 | 46 | define three_div : fn Pos -> Nat = λd{ ℕ3 / d } 47 | assert default(after(nat2pos(ℕ3), three_div), ℕ0) = ℕ1 48 | -------------------------------------------------------------------------------- /test/should-validate/all1.pf: -------------------------------------------------------------------------------- 1 | theorem T: all x : bool. x = x 2 | proof 3 | arbitrary x:bool 4 | conclude x = x by . 5 | end -------------------------------------------------------------------------------- /test/should-validate/all2.pf: -------------------------------------------------------------------------------- 1 | theorem T: all p : bool. if p then p 2 | proof 3 | arbitrary p : bool 4 | suppose P: p 5 | P 6 | end 7 | -------------------------------------------------------------------------------- /test/should-validate/all3.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool , Q:bool . if P and Q then Q and P 2 | proof 3 | arbitrary P:bool, R:bool 4 | suppose pr: P and R 5 | have p: P by pr 6 | have r: R by pr 7 | conclude R and P by r , p 8 | end -------------------------------------------------------------------------------- /test/should-validate/append_assoc.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | theorem T: ([1,2] ++ [3,4]) ++ [5,6] = [1,2] ++ ([3,4] ++ [5,6]) 5 | proof 6 | . 7 | end 8 | 9 | -------------------------------------------------------------------------------- /test/should-validate/array1.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | define L = [1,2,3] 5 | define A = array(L) 6 | assert A[0] = 1 7 | assert A[1] = 2 8 | assert A[2] = 3 9 | -------------------------------------------------------------------------------- /test/should-validate/array3.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | define L = [1,2,3] 5 | define A = array(L) 6 | define i = 0 7 | define j = 1 8 | define k = 2 9 | assert A[i] = 1 10 | assert A[j] = 2 11 | assert A[k] = 3 12 | -------------------------------------------------------------------------------- /test/should-validate/assoc1.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: all x:Nat,y:Nat,z:Nat. 4 | x + suc(y) + z = suc(x + y + z) 5 | proof 6 | arbitrary x:Nat,y:Nat,z:Nat 7 | equations 8 | x + suc(y) + z 9 | = suc(x + y) + z by replace add_suc. 10 | ... = suc(x + y + z) by replace suc_add. 11 | end 12 | -------------------------------------------------------------------------------- /test/should-validate/assoc2.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: all x:Nat,y:Nat,z:Nat. 4 | x + y + suc(z) = suc(x + y + z) 5 | proof 6 | arbitrary x:Nat,y:Nat,z:Nat 7 | equations 8 | x + y + suc(z) 9 | = x + suc(y + z) by replace add_suc. 10 | ... = suc(x + y + z) by replace add_suc. 11 | end 12 | -------------------------------------------------------------------------------- /test/should-validate/assoc3.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: all a:Nat, x:Nat, y:Nat, z:Nat. 4 | a + suc(x) + y + z = suc(a + x + y + z) 5 | proof 6 | arbitrary a:Nat, x:Nat, y:Nat, z:Nat 7 | equations 8 | a + suc(x) + y + z 9 | = a + suc(x + y) + z by expand operator+. 10 | ... = a + suc(x + y + z) by expand operator+. 11 | ... = suc(a + x + y + z) by replace add_suc. 12 | end 13 | -------------------------------------------------------------------------------- /test/should-validate/bicond1.pf: -------------------------------------------------------------------------------- 1 | theorem iff1: true <=> true 2 | proof 3 | . 4 | end 5 | 6 | theorem iff2: false <=> false 7 | proof 8 | . 9 | end 10 | -------------------------------------------------------------------------------- /test/should-validate/bicond2.pf: -------------------------------------------------------------------------------- 1 | import List 2 | import UInt 3 | 4 | theorem empty_iff_0: all E:type. all l:List. 5 | length(l) = 0 <=> l = empty 6 | proof 7 | arbitrary E:type 8 | arbitrary l : List 9 | have s1 : if l = empty then length(l) = 0 by { 10 | suppose prem 11 | suffices length(@empty) = 0 by replace prem. 12 | expand length. 13 | } 14 | have s2 : if length(l) = 0 then l = empty 15 | by switch l { 16 | case empty { . } 17 | case node(n, xs') { 18 | suppose len_z 19 | conclude false 20 | by apply uint_not_one_add_zero[length(xs')] to 21 | expand length in len_z 22 | } 23 | } 24 | s1, s2 25 | end 26 | 27 | 28 | theorem len_rev_empty_zero: all E:type. 29 | length(reverse(@empty)) = 0 30 | proof 31 | suffices (all E:type. length(@empty) = 0) by expand reverse. 32 | arbitrary E : type 33 | have step: length(@empty) = 0 <=> @empty = @empty 34 | by empty_iff_0[@empty] 35 | have ee: @empty = @empty by . 36 | apply step to ee 37 | end 38 | -------------------------------------------------------------------------------- /test/should-validate/bicond3.pf: -------------------------------------------------------------------------------- 1 | theorem bicond_commute : all P : bool, Q : bool. 2 | if P <=> Q then Q <=> P 3 | proof 4 | arbitrary P : bool, Q : bool 5 | switch P { 6 | case true assume prop_t { . } 7 | case false assume prop_f { . } 8 | } 9 | end -------------------------------------------------------------------------------- /test/should-validate/bicond4.pf: -------------------------------------------------------------------------------- 1 | theorem bicond_trans : all P : bool, Q : bool, R : bool. 2 | if (P <=> Q) and (Q <=> R) then P <=> R 3 | proof 4 | arbitrary P : bool, Q : bool, R : bool 5 | switch P { 6 | case true assume prop_t { 7 | switch Q { 8 | case true assume prop_t' { 9 | . 10 | } 11 | case false assume prop_f { 12 | . 13 | } 14 | } 15 | } 16 | case false assume prop_f { 17 | switch Q { 18 | case true assume prop_t { 19 | . 20 | } 21 | case false assume prop_f' { 22 | . 23 | } 24 | } 25 | } 26 | } 27 | end -------------------------------------------------------------------------------- /test/should-validate/bintree.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | recursive operator +(Nat,Nat) -> Nat { 7 | operator +(zero, m) = m 8 | operator +(suc(n), m) = suc(n + m) 9 | } 10 | 11 | recursive max(Nat,Nat) -> Nat { 12 | max(zero, n) = n 13 | max(suc(m'), n) = 14 | switch n { 15 | case zero { suc(m') } 16 | case suc(n') { suc(max(m',n')) } 17 | } 18 | } 19 | 20 | union Tree { 21 | empty 22 | node(Nat, Tree, Tree) 23 | } 24 | 25 | recursive height(Tree) -> Nat { 26 | height(empty) = ℕ0 27 | height(node(n,L,R)) = ℕ1 + max(height(L), height(R)) 28 | } 29 | 30 | recursive sum(Tree) -> Nat { 31 | sum(empty) = ℕ0 32 | sum(node(n,L,R)) = n + sum(L) + sum(R) 33 | } 34 | 35 | /* 36 | t3= 4 37 | / \ 38 | t1= 3 7 =t2 39 | 40 | */ 41 | 42 | define t1 = node(suc(suc(suc(zero))), empty, empty) 43 | define t2 = node(ℕ7, empty, empty) 44 | define t3 = node(ℕ4, t1, t2) 45 | 46 | assert height(t3) = ℕ2 47 | assert sum(t3) = ℕ14 48 | 49 | -------------------------------------------------------------------------------- /test/should-validate/comp_switchcase.pf: -------------------------------------------------------------------------------- 1 | // This is here because it was previously an error 2 | 3 | theorem idek : all A : bool, B : bool. 4 | if (switch A { case true { false } case false {false}}) then B 5 | 6 | proof 7 | arbitrary A:bool, B:bool 8 | suppose prem 9 | switch A { 10 | case true assume prop_t { 11 | have prem' : switch A { case true{false} case false{false} } 12 | by prem 13 | replace prop_t in prem' 14 | } 15 | case false assume prop_f { 16 | replace prop_f in prem 17 | } 18 | } 19 | end 20 | -------------------------------------------------------------------------------- /test/should-validate/conditional1.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T1: if ℕ0 ≤ ℕ1 then true else false 4 | proof 5 | expand operator ≤. 6 | end 7 | -------------------------------------------------------------------------------- /test/should-validate/define_cases.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool. if (define x = P; (x or Q)) and (not P) then Q 2 | proof 3 | arbitrary P:bool, Q:bool 4 | assume prem 5 | cases conjunct 0 of prem 6 | case p { 7 | conclude false by apply (conjunct 1 of prem) to p 8 | } 9 | case q { 10 | q 11 | } 12 | end 13 | -------------------------------------------------------------------------------- /test/should-validate/definition_in.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | define x = ℕ0 4 | define y = ℕ1 5 | 6 | theorem T: all z:Nat. if z = x + y then z = ℕ1 7 | proof 8 | arbitrary z:Nat 9 | assume zxy: z = x + y 10 | expand x | y | operator+ in zxy 11 | end 12 | -------------------------------------------------------------------------------- /test/should-validate/empty_file.pf: -------------------------------------------------------------------------------- 1 | // Only a comment -------------------------------------------------------------------------------- /test/should-validate/eval-fact.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: all x:Nat. if x = ℕ1 + ℕ2 + ℕ3 then x = ℕ6 4 | proof 5 | arbitrary x:Nat 6 | assume prem: x = ℕ1 + ℕ2 + ℕ3 7 | evaluate in prem 8 | end 9 | -------------------------------------------------------------------------------- /test/should-validate/eval-goal.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | theorem T: 1 + 2 + 3 = 2 + 2 + 2 4 | proof 5 | evaluate 6 | end 7 | -------------------------------------------------------------------------------- /test/should-validate/fib_switch.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | recfun fib(n : Nat) -> Nat 4 | measure n of Nat 5 | { 6 | switch n { 7 | case 0 { ℕ0 } 8 | case suc(n1) { 9 | switch n1 { 10 | case 0 { ℕ1 } 11 | case suc(n2) { 12 | fib(n1) + fib(n2) 13 | } 14 | } 15 | } 16 | } 17 | } 18 | terminates { 19 | arbitrary n:Nat 20 | have A: all n1:Nat, n2:Nat. if (n = suc(n1) and n1 = suc(n2)) then n1 < n by { 21 | arbitrary n1:Nat, n2:Nat 22 | assume prem: n = suc(n1) and n1 = suc(n2) 23 | suffices suc(n2) < suc(suc(n2)) 24 | by replace conjunct 0 of prem | conjunct 1 of prem. 25 | suffices suc(suc(n2)) ≤ suc(suc(n2)) by expand operator <. 26 | less_equal_refl 27 | } 28 | have B: all n1:Nat, n2:Nat. if (n = suc(n1) and n1 = suc(n2)) then n2 < n by { 29 | arbitrary n1:Nat, n2:Nat 30 | assume prem: n = suc(n1) and n1 = suc(n2) 31 | suffices n2 < suc(suc(n2)) 32 | by replace conjunct 0 of prem | conjunct 1 of prem. 33 | suffices suc(n2) ≤ suc(suc(n2)) by expand operator <. 34 | less_equal_suc 35 | } 36 | A, B 37 | } 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /test/should-validate/fun1.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | define f = (λm{m} : fn UInt->UInt) 4 | 5 | theorem T: f(0) = 0 6 | proof 7 | expand f. 8 | end 9 | -------------------------------------------------------------------------------- /test/should-validate/fun_zero_param.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | fun five() { 4 | 5 5 | } 6 | 7 | assert five() = 5 8 | -------------------------------------------------------------------------------- /test/should-validate/function1.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import Pair 3 | 4 | fun swap(p : Pair) { 5 | pair(second(p), first(p)) 6 | } 7 | 8 | assert swap(pair(1,2)) = pair(2,1) 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test/should-validate/function2.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import Pair 3 | 4 | fun swap(p : Pair) { 5 | pair(second(p), first(p)) 6 | } 7 | 8 | assert swap(pair(1,2)) = pair(2,1) 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test/should-validate/generic-fun.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | define id = fun x:T { x } 4 | 5 | assert id(42) = 42 6 | -------------------------------------------------------------------------------- /test/should-validate/generic-fun2.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import Pair 3 | 4 | define swap = fun p:Pair { pair(second(p), first(p)) } 5 | 6 | assert first(swap(pair(1,2))) = 2 7 | assert second(swap(pair(1,2))) = 1 8 | -------------------------------------------------------------------------------- /test/should-validate/generic-syth.pf: -------------------------------------------------------------------------------- 1 | define id = generic T { λ y:T { y } } 2 | 3 | theorem T: id(true) = true 4 | proof 5 | expand id. 6 | end 7 | -------------------------------------------------------------------------------- /test/should-validate/generic1.pf: -------------------------------------------------------------------------------- 1 | define some_equal : fn T -> bool 2 | = generic T { λ y { some x:T. x = y } } 3 | 4 | theorem T: some_equal(true) 5 | proof 6 | suffices some x:bool. x = true by expand some_equal. 7 | choose true. 8 | end 9 | -------------------------------------------------------------------------------- /test/should-validate/generic2.pf: -------------------------------------------------------------------------------- 1 | define some_equal : fn T -> bool 2 | = generic T { λ y { some x:T. x = y } } 3 | 4 | theorem T: @some_equal(true) 5 | proof 6 | suffices some x:bool. x = true by expand some_equal. 7 | choose true. 8 | end 9 | -------------------------------------------------------------------------------- /test/should-validate/implicit_modus_ponens.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | theorem T: 2 ≤ 1 + 1 4 | proof 5 | have X: 2 = 1 + 1 by evaluate 6 | uint_equal_implies_less_equal[2, 1+1], X 7 | end 8 | -------------------------------------------------------------------------------- /test/should-validate/induction1.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | recursive add(Nat,Nat) -> Nat { 7 | add(zero, m) = m 8 | add(suc(n), m) = suc(add(n, m)) 9 | } 10 | 11 | theorem add_zero: all n:Nat. add(n, zero) = n 12 | proof 13 | induction Nat 14 | case zero { 15 | conclude add(zero, zero) = zero by expand add. 16 | } 17 | case suc(n') suppose IH { 18 | equations 19 | add(suc(n'), zero) = suc(add(n', zero)) by expand add. 20 | ... = suc(n') by replace IH. 21 | } 22 | end 23 | 24 | -------------------------------------------------------------------------------- /test/should-validate/induction_auto_assume.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem add_zero_auto: all x:Nat. x + ℕ0 = x 4 | proof 5 | induction Nat 6 | case 0 { evaluate } 7 | case suc(n') { 8 | suffices suc(n' + ℕ0) = suc(n') by evaluate 9 | replace recall n' + ℕ0 = n'. 10 | } 11 | end 12 | -------------------------------------------------------------------------------- /test/should-validate/inst1.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: 4 | if (all x:Nat. x = x) 5 | then ℕ1 = ℕ1 6 | proof 7 | suppose xeqx 8 | xeqx[ℕ1] 9 | end 10 | -------------------------------------------------------------------------------- /test/should-validate/inst2.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: 4 | if (all x:Nat. if x = ℕ0 then suc(x) = ℕ1) 5 | then ℕ1 = ℕ1 6 | proof 7 | suppose prem 8 | have zz: ℕ0 = ℕ0 by . 9 | apply prem to zz 10 | end 11 | -------------------------------------------------------------------------------- /test/should-validate/inst3.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | theorem thm: if ( all xs:List. map(xs, fun x:T { x }) = xs) 5 | then map(node(1, empty), fun x:UInt { x }) = node(1, empty) 6 | proof 7 | suppose prem: ( all xs:List. map(xs, fun x:T { x }) = xs) 8 | prem[node(1,empty)] 9 | end 10 | -------------------------------------------------------------------------------- /test/should-validate/inst4.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import List 3 | 4 | theorem thm: if ( all xs:List. map(xs, fun x:T { x }) = xs) 5 | then map(node(ℕ1, empty), fun x:Nat { x }) = node(ℕ1, empty) 6 | proof 7 | suppose prem: ( all xs:List. map(xs, fun x:T { x }) = xs) 8 | prem 9 | end 10 | -------------------------------------------------------------------------------- /test/should-validate/inst5.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | theorem T: all xs:List. if length(xs) = 0 then xs = [] 5 | proof 6 | arbitrary xs:List 7 | assume prem: length(xs) = 0 8 | apply length_zero_empty to prem 9 | end 10 | -------------------------------------------------------------------------------- /test/should-validate/int1.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import Int 3 | 4 | // Negation 5 | assert -pos(5) = negsuc(4) 6 | assert -negsuc(4) = pos(5) 7 | assert -pos(0) = pos(0) 8 | assert -negsuc(0) = pos(1) 9 | assert -+5 = -5 10 | assert --5 = +5 11 | assert -+0 = +0 12 | assert --1 = +1 13 | // negation nats 14 | assert -5 = negsuc(4) 15 | assert -0 = pos(0) 16 | 17 | // Addition 18 | assert pos(1) + pos(2) = pos(3) // 1 + 2 19 | assert negsuc(5) + negsuc(3) = negsuc(9) // -6 + -4 20 | assert negsuc(2) + pos(2) = negsuc(0) // -3 + 2 21 | assert negsuc(2) + pos(4) = pos(1) // -3 + 4 22 | assert pos(3) + negsuc(2) = pos(0) // 3 + -3 23 | assert pos(3) + negsuc(9) = negsuc(6) // 3 + -10 24 | // addition ints and nats 25 | assert 1 + pos(2) = pos(3) // 1 + 2 26 | assert negsuc(5) + negsuc(3) = negsuc(9) // -6 + -4 27 | assert negsuc(2) + 2 = negsuc(0) // -3 + 2 28 | assert negsuc(2) + 4 = pos(1) // -3 + 4 29 | assert 3 + negsuc(2) = pos(0) // 3 + -3 30 | assert 3 + negsuc(9) = negsuc(6) // 3 + -10 31 | assert +1 + +2 = +3 32 | assert -6 + -4 = -10 33 | assert -3 + +2 = -1 34 | assert -3 + +4 = +1 35 | assert +3 + -3 = +0 36 | assert +3 + -10 = -7 37 | 38 | // Subtraction 39 | assert pos(1) - pos(1) = pos(0) // 1 - 1 40 | assert pos(1) - pos(2) = negsuc(0) // 1 - 2 41 | assert pos(2) - pos(1) = pos(1) // 2 - 1 42 | assert negsuc(0) - pos(1) = negsuc(1) // -1 - 1 43 | assert negsuc(0) - pos(2) = negsuc(2) // -1 - 2 44 | assert negsuc(1) - pos(1) = negsuc(2) // -2 - 1 45 | assert pos(1) - negsuc(0) = pos(2) // 1 - -1 46 | assert pos(1) - negsuc(1) = pos(3) // 1 - -2 47 | assert pos(2) - negsuc(0) = pos(3) // 2 - -1 48 | assert +1 - +1 = +0 49 | assert +1 - +2 = -1 50 | assert +2 - +1 = +1 51 | assert -1 - +1 = -2 52 | assert -1 - +2 = -3 53 | assert -2 - +1 = -3 54 | assert +1 - -1 = +2 55 | assert +1 - -2 = +3 56 | assert +2 - -1 = +3 57 | // Subtraction ints and nats 58 | assert 1 - pos(1) = pos(0) // 1 - 1 59 | assert 1 - pos(2) = negsuc(0) // 1 - 2 60 | assert 2 - pos(1) = pos(1) // 2 - 1 61 | assert negsuc(0) - 1 = negsuc(1) // -1 - 1 62 | assert negsuc(0) - 2 = negsuc(2) // -1 - 2 63 | assert negsuc(1) - 1 = negsuc(2) // -2 - 1 64 | assert 1 - negsuc(0) = pos(2) // 1 - -1 65 | assert 1 - negsuc(1) = pos(3) // 1 - -2 66 | assert 2 - negsuc(0) = pos(3) // 2 - -1 67 | 68 | // Multiplication 69 | assert pos(1) * pos(1) = pos(1) // 1 * 1 70 | assert pos(2) * pos(4) = pos(8) // 2 * 4 71 | assert negsuc(1) * pos(3) = negsuc(5) // -2 * 3 72 | assert negsuc(2) * pos(4) = negsuc(11) // -3 * 4 73 | assert negsuc(2) * negsuc(3) = pos(12) // -3 * -4 74 | assert pos(2) * negsuc(9) = negsuc(19) // 2 * -10 75 | -------------------------------------------------------------------------------- /test/should-validate/list1.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import Nat 3 | import List 4 | 5 | recursive length2(List) -> UInt { 6 | length2([]) = 0 7 | length2(node(n, next)) = 1 + length2(next) 8 | } 9 | 10 | assert @[] = @empty 11 | assert [1, 2, 3] = node(1, node(2, node(3, empty))) 12 | 13 | assert length(@[]) = 0 14 | assert length([1, 2, 3]) = 3 15 | assert length2(@[]) = length(@[]) 16 | assert length2([1, 2, 3]) = length([1, 2, 3]) 17 | 18 | assert [1, 2] ++ [3, 4] = [1, 2, 3, 4] 19 | assert [1, 2] ++ node(3, node(4, empty)) = node(1, node(2, empty)) ++ [3, 4] 20 | 21 | assert reverse([1, 2, 3]) = node(3, node(2, node(1, empty))) 22 | 23 | assert set_of([1, 2, 3]) = set_of(node(1, node(2, node(3, empty)))) 24 | 25 | assert map([1, 2, 3], (fun x { 1 + x } : fn UInt -> UInt)) = [2, 3, 4] 26 | -------------------------------------------------------------------------------- /test/should-validate/list2.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | theorem length_node42: length([42]) = 1 5 | proof 6 | suffices 1 + 0 = 1 7 | by expand 2*length. 8 | uint_add_zero[1] 9 | end 10 | 11 | theorem length_one_nat_again: all x:UInt. length([x]) = 1 12 | proof 13 | arbitrary x:UInt 14 | suffices 1 + 0 = 1 15 | by expand 2*length. 16 | uint_add_zero[1] 17 | end 18 | 19 | theorem append_xy: 20 | all T:type. all x:T, y:T. [x] ++ [y] = [x, y] 21 | proof 22 | arbitrary T:type 23 | arbitrary x:T, y:T 24 | expand 2*operator ++. 25 | end 26 | 27 | theorem length_one_equal: all U:type. all x:U, y:U. 28 | length([x]) = length([y]) 29 | proof 30 | arbitrary U:type 31 | arbitrary x:U, y:U 32 | evaluate 33 | end 34 | 35 | 36 | theorem append_empty_again: all U :type. all xs :List. 37 | xs ++ [] = xs 38 | proof 39 | arbitrary U:type 40 | induction List 41 | case [] { 42 | conclude @[] ++ [] = [] by expand operator++. 43 | } 44 | case node(n, xs') suppose IH: xs' ++ empty = xs' { 45 | equations 46 | node(n,xs') ++ empty 47 | = node(n, xs' ++ empty) by expand operator++. 48 | ... = node(n,xs') by replace IH. 49 | } 50 | end 51 | -------------------------------------------------------------------------------- /test/should-validate/mark1.pf: -------------------------------------------------------------------------------- 1 | 2 | theorem T: all P:bool, Q:bool. 3 | if Q = P and P 4 | then Q and Q 5 | proof 6 | arbitrary P:bool, Q:bool 7 | suppose prem: (Q = P and P) 8 | have q_p: Q = P 9 | by prem 10 | conclude Q and #Q# by { 11 | replace q_p 12 | show #Q# and P 13 | replace q_p 14 | show P and P 15 | prem 16 | } 17 | end 18 | -------------------------------------------------------------------------------- /test/should-validate/mark2.pf: -------------------------------------------------------------------------------- 1 | union U { 2 | foo 3 | } 4 | 5 | fun f(u : U) { 6 | switch u { 7 | case foo { true } 8 | } 9 | } 10 | 11 | fun h(u : U) { 12 | switch u { 13 | case foo { f(foo) } 14 | } 15 | } 16 | 17 | fun g(u : U) { 18 | switch u { 19 | case foo { h(foo) } 20 | } 21 | } 22 | 23 | theorem T: (h(foo) and g(foo)) = (f(foo) and h(foo)) 24 | proof 25 | // removing the mark causes this to fail, as intended. -Jeremy 26 | conclude # h(foo) and g(foo) # = (f(foo) and h(foo)) 27 | by expand h | g. 28 | end 29 | -------------------------------------------------------------------------------- /test/should-validate/mark3.pf: -------------------------------------------------------------------------------- 1 | union C { 2 | c 3 | } 4 | 5 | fun f(x : C) { 6 | switch x { 7 | case c { true } 8 | } 9 | } 10 | 11 | theorem T: (f(c) and f(c)) = (f(c) and f(c)) 12 | proof 13 | equations 14 | (#f(c)# and f(c)) = (true and f(c)) by expand f. 15 | $ (true and #f(c)#) = (true and true) by expand f. 16 | ... = (#f(c)# and true) by expand f. 17 | ... = (f(c) and #f(c)#) by expand f. 18 | end 19 | -------------------------------------------------------------------------------- /test/should-validate/not_equal.pf: -------------------------------------------------------------------------------- 1 | assert true ≠ false -------------------------------------------------------------------------------- /test/should-validate/opaque_define.pf: -------------------------------------------------------------------------------- 1 | import OpaqueTests 2 | 3 | assert f_id(one(Z)) = one(Z) 4 | assert f_id(zero(Z)) = zero(Z) 5 | -------------------------------------------------------------------------------- /test/should-validate/opaque_genrec_fun.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import OpaqueTests 3 | 4 | assert fact(ℕ5) = ℕ120 5 | -------------------------------------------------------------------------------- /test/should-validate/opaque_print.pf: -------------------------------------------------------------------------------- 1 | import OpaqueTests 2 | 3 | print another_five -------------------------------------------------------------------------------- /test/should-validate/opaque_rec_fun.pf: -------------------------------------------------------------------------------- 1 | import OpaqueTests 2 | 3 | assert f_z(one(Z)) = Z 4 | assert f_z(zero(Z)) = Z -------------------------------------------------------------------------------- /test/should-validate/opaque_union.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | import OpaqueTests 3 | 4 | print natToNatHat(ℕ5) 5 | -------------------------------------------------------------------------------- /test/should-validate/overload1.pf: -------------------------------------------------------------------------------- 1 | union A { 2 | a 3 | } 4 | 5 | union B { 6 | b 7 | } 8 | 9 | union C { 10 | c 11 | } 12 | 13 | union D { 14 | d 15 | } 16 | 17 | define f : fn A -> bool = λ x { true } 18 | define f : fn B -> bool = λ x { false } 19 | define f : fn C -> bool = λ x { true } 20 | define f : fn D -> bool = λ x { false } 21 | 22 | assert f(a) 23 | assert not f(b) 24 | assert f(c) 25 | assert not f(d) -------------------------------------------------------------------------------- /test/should-validate/overload3.pf: -------------------------------------------------------------------------------- 1 | union A { 2 | a 3 | } 4 | 5 | union B { 6 | b 7 | } 8 | 9 | union C1 { 10 | Make(A) 11 | } 12 | 13 | union C2 { 14 | Make(B) 15 | } 16 | 17 | assert Make(a) = Make(a) 18 | assert Make(b) = Make(b) -------------------------------------------------------------------------------- /test/should-validate/overload5.pf: -------------------------------------------------------------------------------- 1 | union A { 2 | a 3 | } 4 | 5 | union B { 6 | b 7 | } 8 | 9 | union C { 10 | c 11 | } 12 | 13 | union D { 14 | d 15 | } 16 | 17 | fun f(x : A) { 18 | switch x { 19 | case a { true } 20 | } 21 | } 22 | 23 | fun f(x : B) { 24 | switch x { 25 | case b { false } 26 | } 27 | } 28 | 29 | fun f(x : C) { 30 | switch x { 31 | case c { true } 32 | } 33 | } 34 | 35 | fun f(x : D) { 36 | switch x { 37 | case d { false } 38 | } 39 | } 40 | 41 | assert f(a) 42 | assert not f(b) 43 | assert f(c) 44 | assert not f(d) 45 | -------------------------------------------------------------------------------- /test/should-validate/overload_and_definition.pf: -------------------------------------------------------------------------------- 1 | union A { a } 2 | union B { b } 3 | 4 | define f : fn A -> bool = λ x { true } 5 | define f : fn B -> bool = λ x { false } 6 | 7 | assert f(a) 8 | assert not f(b) 9 | 10 | theorem f_true : f(a) 11 | proof 12 | expand f. 13 | end 14 | 15 | theorem f_false : not f(b) 16 | proof 17 | expand f. 18 | end 19 | -------------------------------------------------------------------------------- /test/should-validate/postulate1.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | postulate triple : all x:UInt. 3*x = x + x + x 4 | 5 | theorem quad: all x:UInt. 4*x = x + x + x + x 6 | proof 7 | arbitrary x:UInt 8 | have A: 4 = 1 + 3 by evaluate 9 | replace A 10 | replace uint_dist_mult_add_right 11 | replace triple 12 | replace uint_one_mult. 13 | end 14 | -------------------------------------------------------------------------------- /test/should-validate/private_define.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | private define f : fn UInt -> UInt = fun x{ x + x } 4 | 5 | assert f(1) = 2 6 | -------------------------------------------------------------------------------- /test/should-validate/private_function.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | private recursive add_one_all(List) -> List { 5 | add_one_all([]) = [] 6 | add_one_all(node(x, xs)) = node(1 + x, add_one_all(xs)) 7 | } 8 | 9 | assert add_one_all([1, 2, 3, 4]) = [2,3,4,5] 10 | -------------------------------------------------------------------------------- /test/should-validate/private_union.pf: -------------------------------------------------------------------------------- 1 | private union Bit { 2 | High 3 | Low 4 | } 5 | 6 | assert High = High 7 | assert Low = Low 8 | assert Low /= High 9 | assert High /= Low -------------------------------------------------------------------------------- /test/should-validate/rec1.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | recursive add(Nat,Nat) -> Nat { 7 | add(zero, m) = m 8 | add(suc(n), m) = suc(add(n, m)) 9 | } 10 | 11 | define f : fn Nat,Nat,Nat->Nat = λ x, y, z { add(add(x,y),z) } 12 | 13 | assert f(zero, suc(zero), suc(suc(zero))) = suc(suc(suc(zero))) 14 | assert add(zero, suc(zero)) = suc(zero) 15 | assert add(suc(zero), zero) = suc(zero) 16 | -------------------------------------------------------------------------------- /test/should-validate/rec2.pf: -------------------------------------------------------------------------------- 1 | union Nat { 2 | zero 3 | suc(Nat) 4 | } 5 | 6 | recursive add(Nat,Nat) -> Nat { 7 | add(zero, m) = m 8 | add(suc(n), m) = suc(add(n, m)) 9 | } 10 | 11 | define f : fn Nat,Nat,Nat->Nat = λ x, y, z { add(add(x,y),z) } 12 | 13 | assert f(zero, suc(zero), suc(suc(zero))) = suc(suc(suc(zero))) 14 | assert add(zero, suc(zero)) = suc(zero) 15 | assert add(suc(zero), zero) = suc(zero) 16 | -------------------------------------------------------------------------------- /test/should-validate/recall1.pf: -------------------------------------------------------------------------------- 1 | theorem T: if false then false 2 | proof 3 | suppose: false 4 | recall false 5 | end 6 | -------------------------------------------------------------------------------- /test/should-validate/replace_generic.pf: -------------------------------------------------------------------------------- 1 | union List { 2 | empty 3 | } 4 | 5 | union Nat { 6 | zero 7 | } 8 | 9 | fun length(xs : List) { zero } 10 | 11 | fun operator +(a : Nat, b : Nat) { b } 12 | 13 | fun operator *(a : Nat, b : Nat) { zero } 14 | 15 | fun operator ++ (xs : List, ys : List) { ys } 16 | 17 | postulate len_app: all T:type, xs:List, ys:List. 18 | length(xs ++ ys) = length(xs) + length(ys) 19 | 20 | theorem foo: all U:type, ls:List. 21 | length(ls ++ ls) = length(ls) + ℕ0 + length(ls) 22 | proof 23 | arbitrary U:type, ls:List 24 | replace len_app 25 | expand operator+. 26 | end 27 | 28 | -------------------------------------------------------------------------------- /test/should-validate/rewrite_all_mark.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: all n:Nat. (ℕ0 + n) + (ℕ0 + n) = n + n 4 | proof 5 | arbitrary n:Nat 6 | have eq1: # ℕ0 + n # + (ℕ0 + n) = n + (ℕ0 + n) 7 | by replace zero_add. 8 | have eq2: n + (ℕ0 + n) = n + n 9 | by replace zero_add. 10 | transitive eq1 eq2 11 | end 12 | -------------------------------------------------------------------------------- /test/should-validate/rewrite_with_all.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | theorem T: all n:UInt. 1 + (0 + n) = 1 + n 4 | proof 5 | replace uint_zero_add. 6 | end 7 | -------------------------------------------------------------------------------- /test/should-validate/some1.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | theorem T: some x : Nat. x = x 4 | proof 5 | choose ℕ0 6 | reflexive 7 | end 8 | -------------------------------------------------------------------------------- /test/should-validate/some2.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | 3 | theorem T: if (some x:UInt. x = 0) then (some x:UInt. x = 1) 4 | proof 5 | suppose prem 6 | obtain y where yeqz from prem 7 | choose 1 + y 8 | replace yeqz 9 | evaluate 10 | end 11 | -------------------------------------------------------------------------------- /test/should-validate/suffices1.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. if (if P then Q) and (if Q then R) and P then R 2 | proof 3 | arbitrary P:bool, Q:bool, R:bool 4 | suppose prem 5 | suffices Q by prem 6 | suffices P by prem 7 | prem 8 | end 9 | -------------------------------------------------------------------------------- /test/should-validate/suffices_def.pf: -------------------------------------------------------------------------------- 1 | 2 | define d = true 3 | 4 | theorem T: d 5 | proof 6 | suffices true by expand d. 7 | . 8 | end 9 | 10 | -------------------------------------------------------------------------------- /test/should-validate/suffices_implies_omitted.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool. if P and (if P then Q) then Q 2 | proof 3 | arbitrary P:bool, Q:bool 4 | assume prem: (P and (if P then Q)) 5 | have pq: if P then Q by prem 6 | suffices __ by pq 7 | conclude P by prem 8 | end 9 | -------------------------------------------------------------------------------- /test/should-validate/suffices_omitted.pf: -------------------------------------------------------------------------------- 1 | import UInt 2 | import List 3 | 4 | theorem length__nat_one: all x:UInt. length([x]) = 1 5 | proof 6 | arbitrary x:UInt 7 | expand 2*length 8 | uint_add_zero[1] 9 | end 10 | 11 | 12 | theorem length__nat_one': all x:UInt. length([x]) = 1 13 | proof 14 | arbitrary x:UInt 15 | expand 2*length 16 | uint_add_zero[1] 17 | end 18 | -------------------------------------------------------------------------------- /test/should-validate/suffices_rewrite.pf: -------------------------------------------------------------------------------- 1 | 2 | theorem T: all a:bool, b:bool. if b = a and a then b 3 | proof 4 | arbitrary a:bool, b:bool 5 | suppose prem 6 | suffices a by replace conjunct 0 of prem. 7 | conjunct 1 of prem 8 | end 9 | -------------------------------------------------------------------------------- /test/should-validate/switch_auto_assume.pf: -------------------------------------------------------------------------------- 1 | union A { 2 | a 3 | b 4 | } 5 | 6 | fun test(x : A){ 7 | switch x { 8 | case a { true } 9 | case b { false } 10 | } 11 | } 12 | 13 | 14 | theorem test_thm: all x:A. test(x) = true or test(x) = false 15 | proof 16 | arbitrary x:A 17 | switch x { 18 | case a assume G { 19 | replace symmetric G 20 | show test(x) = true 21 | replace G 22 | show test(a) = true 23 | evaluate 24 | } 25 | case b { 26 | replace symmetric recall x = b 27 | show test(x) = false 28 | replace recall x = b 29 | show test(b) = false 30 | evaluate 31 | } 32 | } 33 | end 34 | -------------------------------------------------------------------------------- /test/should-validate/switch_auto_assume_bool.pf: -------------------------------------------------------------------------------- 1 | union A { 2 | a 3 | b 4 | } 5 | 6 | fun test2(x : A){ 7 | if x = a then true else false 8 | } 9 | 10 | theorem test2_thm: all x:A. test2(x) = true or test2(x) = false 11 | proof 12 | arbitrary x:A 13 | suffices ((if x = a then true else false) = true or (if x = a then true else false) = false) 14 | by expand test2. 15 | switch x = a { 16 | case true{ 17 | replace symmetric recall (x = a) = true 18 | show x=a 19 | replace recall (x = a) = true. 20 | } 21 | case false assume G { 22 | . 23 | } 24 | } 25 | end 26 | -------------------------------------------------------------------------------- /test/should-validate/switch_case_alpha.pf: -------------------------------------------------------------------------------- 1 | union Wrapper { 2 | b(bool) 3 | } 4 | 5 | define eval = fun x : Wrapper { 6 | switch x { 7 | case b(y) { true or y } 8 | } 9 | } 10 | 11 | theorem blah : all b1 : Wrapper. 12 | eval(b1) 13 | proof 14 | arbitrary b1 : Wrapper 15 | suffices switch b1 { case b(y){true or y} } 16 | by expand eval. 17 | switch b1 { 18 | case b(b2) { 19 | . 20 | } 21 | } 22 | end 23 | -------------------------------------------------------------------------------- /test/should-validate/switch_term.pf: -------------------------------------------------------------------------------- 1 | union Bit { 2 | zero 3 | one 4 | } 5 | 6 | define b = zero 7 | 8 | assert switch b { 9 | case zero { true } 10 | case one { false } 11 | } -------------------------------------------------------------------------------- /test/should-validate/theorem_and.pf: -------------------------------------------------------------------------------- 1 | theorem T1: true and true 2 | proof 3 | . , . 4 | end -------------------------------------------------------------------------------- /test/should-validate/theorem_and2.pf: -------------------------------------------------------------------------------- 1 | theorem T2: true and true 2 | proof 3 | . 4 | end -------------------------------------------------------------------------------- /test/should-validate/theorem_and3.pf: -------------------------------------------------------------------------------- 1 | theorem T2: true 2 | proof 3 | . , . 4 | end 5 | -------------------------------------------------------------------------------- /test/should-validate/theorem_and4.pf: -------------------------------------------------------------------------------- 1 | theorem T4: if false then false 2 | proof 3 | suppose f 4 | f , f 5 | end 6 | -------------------------------------------------------------------------------- /test/should-validate/theorem_false1.pf: -------------------------------------------------------------------------------- 1 | theorem false_any: all x:bool, y:bool. if false then x = y 2 | proof 3 | arbitrary x:bool, y:bool 4 | suppose f: false 5 | conclude x = y by f 6 | end -------------------------------------------------------------------------------- /test/should-validate/theorem_false2.pf: -------------------------------------------------------------------------------- 1 | theorem contra_false: all a:bool, b:bool. 2 | if (a = b) and (a = true) and (b = false) then false 3 | proof 4 | arbitrary a:bool, b:bool 5 | suppose prem: a = b and a = true and b = false 6 | have a_true: a = true by prem 7 | have b_true: b = false by prem 8 | 9 | have X: (true = b) and (true = true) and (b = false) 10 | by replace a_true in prem 11 | have Y: (true = true) and (true = true) and (true = false) 12 | by replace b_true in X 13 | have Z: false 14 | by Y 15 | 16 | conclude false by replace a_true | b_true in prem 17 | end 18 | -------------------------------------------------------------------------------- /test/should-validate/theorem_false3.pf: -------------------------------------------------------------------------------- 1 | union U { 2 | foo 3 | bar 4 | } 5 | 6 | theorem foo_bar_false: if foo = bar then false 7 | proof 8 | . 9 | end -------------------------------------------------------------------------------- /test/should-validate/theorem_iff.pf: -------------------------------------------------------------------------------- 1 | theorem iff_trans : all x : bool, y : bool, z : bool. 2 | if (x <=> y) and (y <=> z) then (x <=> z) 3 | proof 4 | arbitrary x:bool, y:bool, z:bool 5 | suppose label 6 | have xtz : if x then z 7 | by suppose px 8 | apply label to (apply label to px) 9 | have ztx : if z then x 10 | by suppose pz 11 | apply label to (apply label to pz) 12 | ztx, xtz 13 | end -------------------------------------------------------------------------------- /test/should-validate/theorem_implies.pf: -------------------------------------------------------------------------------- 1 | theorem T1: if true then true 2 | proof 3 | suppose T 4 | . 5 | end -------------------------------------------------------------------------------- /test/should-validate/theorem_implies2.pf: -------------------------------------------------------------------------------- 1 | theorem T2: if false then false 2 | proof 3 | suppose F 4 | F 5 | end -------------------------------------------------------------------------------- /test/should-validate/theorem_implies3.pf: -------------------------------------------------------------------------------- 1 | theorem T3: if false then false 2 | proof 3 | suppose F: false 4 | F 5 | end -------------------------------------------------------------------------------- /test/should-validate/theorem_implies4.pf: -------------------------------------------------------------------------------- 1 | theorem T: if false then false 2 | proof 3 | suppose f 4 | have ff2f: if (false and true) then false by (suppose _ f) 5 | apply ff2f to . , f 6 | end 7 | -------------------------------------------------------------------------------- /test/should-validate/theorem_implies_mult.pf: -------------------------------------------------------------------------------- 1 | theorem T: all P:bool, Q:bool, R:bool. 2 | if (P and Q and R) then ((if P then Q) and (if Q then R)) 3 | proof 4 | arbitrary P:bool, Q:bool, R:bool 5 | suppose prem 6 | have ptq : if P then Q by suppose P' prem 7 | have qtr : if Q then R by suppose Q' prem 8 | ptq, qtr 9 | end 10 | 11 | 12 | theorem t2: all P:bool, Q:bool, R:bool. 13 | if (P and Q and R) then Q and R 14 | proof 15 | arbitrary P:bool, Q:bool, R:bool 16 | suppose prem : P and Q and R 17 | have step : (if P then Q) and (if Q then R) by apply T[P, Q, R] to prem 18 | apply step to prem 19 | end 20 | -------------------------------------------------------------------------------- /test/should-validate/theorem_let.pf: -------------------------------------------------------------------------------- 1 | theorem T: if false then false 2 | proof 3 | suppose F1: false 4 | have L1: if false then false by (suppose F2 F2) 5 | apply L1 to F1 6 | end 7 | 8 | -------------------------------------------------------------------------------- /test/should-validate/theorem_or.pf: -------------------------------------------------------------------------------- 1 | theorem T: true or false 2 | proof 3 | . 4 | end -------------------------------------------------------------------------------- /test/should-validate/theorem_or2.pf: -------------------------------------------------------------------------------- 1 | theorem T: if false or false then false 2 | proof 3 | suppose ForF { 4 | ForF 5 | /* The following doesn't work because 6 | we reduce a formula before doing cases 7 | to handle things like define getting in the 8 | way. See define_cases.pf. 9 | 10 | cases ForF 11 | case F { F } 12 | case F { F } 13 | */ 14 | } 15 | end 16 | -------------------------------------------------------------------------------- /test/should-validate/theorem_true.pf: -------------------------------------------------------------------------------- 1 | theorem true_is_true: true 2 | proof 3 | . 4 | end 5 | -------------------------------------------------------------------------------- /test/test-imports/OpaqueTests.pf: -------------------------------------------------------------------------------- 1 | import Nat 2 | 3 | opaque define another_five = ℕ5 4 | 5 | // Testing defines 6 | union Byte { 7 | Z 8 | one(Byte) 9 | zero(Byte) 10 | } 11 | 12 | opaque define f_id : fn Byte -> Byte = fun b { b } 13 | 14 | assert f_id(one(Z)) = one(Z) 15 | assert f_id(zero(Z)) = zero(Z) 16 | 17 | theorem f_id_correct : all b:Byte. f_id(b) = b 18 | proof 19 | expand f_id. 20 | end 21 | 22 | // Testing recursive functions 23 | 24 | opaque recursive f_z(Byte) -> Byte { 25 | f_z(Z) = Z 26 | f_z(zero(b)) = f_z(b) 27 | f_z(one(b)) = f_z(b) 28 | } 29 | 30 | assert f_z(one(Z)) = Z 31 | assert f_z(zero(Z)) = Z 32 | 33 | theorem f_Z: all b:Byte. f_z(b) = Z 34 | proof 35 | induction Byte 36 | case Z { 37 | evaluate 38 | } 39 | case one(b) suppose IH { 40 | expand f_z 41 | replace IH 42 | evaluate 43 | } 44 | case zero(b) suppose IH { 45 | expand f_z 46 | replace IH 47 | evaluate 48 | } 49 | end 50 | 51 | 52 | // Testing genrecfun's 53 | 54 | opaque recfun fact(n : Nat) -> Nat 55 | measure n of Nat { 56 | if n = ℕ0 then ℕ1 57 | else n * fact(pred(n)) 58 | } 59 | terminates { 60 | induction Nat 61 | case 0 { 62 | evaluate 63 | } 64 | case suc(n') assume IH { 65 | assume prem: suc(n') /= ℕ0 66 | replace pred_suc_n 67 | suffices __ by evaluate 68 | less_equal_refl 69 | } 70 | } 71 | 72 | theorem some_theorem: fact(ℕ0) = ℕ1 73 | proof 74 | evaluate 75 | end 76 | 77 | theorem some_theorem1: fact(ℕ1) = ℕ1 78 | proof 79 | evaluate 80 | end 81 | 82 | theorem some_theorem2: fact(ℕ5) = ℕ120 83 | proof 84 | evaluate 85 | end 86 | 87 | // Testing opaque unions 88 | opaque union Nat_Hat { 89 | cero 90 | next(Nat_Hat) 91 | } 92 | 93 | // POV: isorecursive types 94 | recursive natToNatHat(Nat) -> Nat_Hat { 95 | natToNatHat(0) = cero 96 | natToNatHat(suc(x)) = next(natToNatHat(x)) 97 | } 98 | 99 | recursive NatHatToNat(Nat_Hat) -> Nat { 100 | NatHatToNat(cero) = ℕ0 101 | NatHatToNat(next(x)) = suc(NatHatToNat(x)) 102 | } 103 | 104 | assert natToNatHat(ℕ1) = next(cero) 105 | 106 | recursive natHats(Nat_Hat, Nat_Hat) -> Nat_Hat { 107 | natHats(cero, y) = y 108 | natHats(next(x), y) = next(natHats(x, y)) 109 | } 110 | 111 | assert natHats(cero, cero) = cero 112 | -------------------------------------------------------------------------------- /test/test-imports/Private.pf: -------------------------------------------------------------------------------- 1 | private union Sign { 2 | positive 3 | negative 4 | } 5 | 6 | lemma cant_import_lemma: true 7 | proof 8 | . 9 | end 10 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "installCommand": "pip install -r live_code_vercel_api/requirements.txt", 4 | "builds": [ 5 | { 6 | "src": "live_code_vercel_api/api.py", 7 | "use": "@vercel/python" 8 | } 9 | ], 10 | "routes": [ 11 | { 12 | "src": "/(.*)", 13 | "dest": "live_code_vercel_api/api.py" 14 | } 15 | ] 16 | } 17 | --------------------------------------------------------------------------------