├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake └── FindEmscripten.cmake ├── cpplint ├── examples ├── CMakeLists.txt ├── index.html ├── jquery.sh ├── minesweeper │ ├── CMakeLists.txt │ ├── agent.h │ ├── eval.sh │ ├── flag.svg │ ├── game.h │ ├── kb.h │ ├── loop.sh │ ├── mine.svg │ ├── minesweeper-js.cc │ ├── minesweeper-js.html │ ├── minesweeper.cc │ ├── printer.h │ ├── test.sh │ └── timer.h ├── sat │ ├── CMakeLists.txt │ ├── functionalize.cc │ ├── limsat.cc │ ├── pigeonhole.c │ ├── pigeons.sh │ ├── sat.cc │ ├── sat.h │ ├── solver.h │ ├── sudoku2cnf.py │ ├── sudoku2fcnf.py │ ├── sudokus.sh │ ├── sum.sh │ ├── update.sh │ └── vg.sh ├── sudoku │ ├── CMakeLists.txt │ ├── agent.h │ ├── game.h │ ├── kb.h │ ├── printer.h │ ├── sudoku-js.cc │ ├── sudoku-js.html │ ├── sudoku.cc │ ├── sudokus.txt │ ├── test-and-eval-sudokus.sh │ ├── test.sh │ └── timer.h ├── tui │ ├── CMakeLists.txt │ ├── README.md │ ├── battleship-pos.hs │ ├── battleship.h │ ├── battleship.txt │ ├── example-battleship-1x4.limbo │ ├── example-birth.limbo │ ├── example-rich-father.limbo │ ├── example-siblings.limbo │ ├── example-unknown-father.limbo │ ├── example-veggie.limbo │ ├── sudoku-rep.py │ ├── sudoku.h │ ├── test-bat.limbo │ ├── test-battleship-1x4.limbo │ ├── test-control.limbo │ ├── test-functions.limbo │ ├── test-guarantee.limbo │ ├── test-introspection-constant.limbo │ ├── test-introspection-disjunction.limbo │ ├── test-introspection-existential.limbo │ ├── test-parents-2.limbo │ ├── test-parents.limbo │ ├── test-propositions.limbo │ ├── test-qbf-1.limbo │ ├── test-qbf-10.limbo │ ├── test-qbf-11.limbo │ ├── test-qbf-12.limbo │ ├── test-qbf-13.limbo │ ├── test-qbf-14.limbo │ ├── test-qbf-15.limbo │ ├── test-qbf-16.limbo │ ├── test-qbf-17.limbo │ ├── test-qbf-2.limbo │ ├── test-qbf-3.limbo │ ├── test-qbf-4.limbo │ ├── test-qbf-5.limbo │ ├── test-qbf-6.limbo │ ├── test-qbf-7.limbo │ ├── test-qbf-8.limbo │ ├── test-qbf-9.limbo │ ├── test-rich-father.limbo │ ├── test-siblings.limbo │ ├── test-unknown-father.limbo │ ├── test-veggie-with-guarantee.limbo │ ├── test-veggie.limbo │ ├── test-ws-zoomed-by.limbo │ ├── timer.h │ ├── tui-js.cc │ ├── tui-js.html │ └── tui.cc ├── upload.sh └── zip.sh ├── src ├── CMakeLists.txt └── limbo │ ├── clause.h │ ├── formula.h │ ├── internal │ ├── dense.h │ ├── hash.h │ ├── ints.h │ ├── maybe.h │ ├── ringbuffer.h │ ├── singleton.h │ └── subsets.h │ ├── io │ ├── input.h │ ├── iocontext.h │ ├── lexer.h │ ├── output.h │ └── parser.h │ ├── limsat.h │ ├── lit.h │ └── sat.h └── tests ├── CMakeLists.txt ├── clause.cc ├── dense.cc ├── formula.cc ├── hash.cc ├── ints.cc ├── limsat.cc ├── lit.cc ├── ringbuffer.cc ├── sat.cc ├── singleton.cc ├── subsets.cc ├── syntax.cc └── syntax.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.so 2 | *.o 3 | *.un~ 4 | 5 | *.swp 6 | *.swo 7 | 8 | *.pyc 9 | 10 | *.log 11 | 12 | callgrind.* 13 | 14 | bla* 15 | 16 | cpplint.py 17 | 18 | CMakeCache.txt 19 | CMakeFiles 20 | CTest*.cmake 21 | cmake_install.cmake 22 | Makefile 23 | compile_commands.json 24 | .ycm_extra_conf.py 25 | DartConfiguration.tcl 26 | target 27 | 28 | Testing 29 | 30 | test-driver 31 | tests/clause-test 32 | tests/dense-test 33 | tests/formula-test 34 | tests/hash-test 35 | tests/ints-test 36 | tests/limsat-test 37 | tests/lit-test 38 | tests/Makefile 39 | tests/ringbuffer-test 40 | tests/sat-test 41 | tests/singleton-test 42 | tests/subsets-test 43 | tests/syntax-test 44 | 45 | examples/minesweeper/minesweeper 46 | examples/minesweeper/minesweeper-js.js* 47 | examples/tui/tui 48 | examples/tui/tui-js.js* 49 | examples/tui/jquery.mousewheel-min.js 50 | examples/tui/jquery.terminal-1.0.10.css 51 | examples/tui/jquery.terminal-1.0.10.min.js 52 | examples/tui/unix_formatting.js 53 | examples/sat/sat 54 | examples/sat/limsat 55 | examples/sat/functionalize 56 | examples/sat/pigeonhole 57 | examples/sat/pigeons 58 | examples/sat/sudokus 59 | examples/sudoku/sudoku 60 | examples/sudoku/sudoku-js.js* 61 | examples/jquery-*.min.js 62 | examples/*/jquery-*.min.js 63 | examples/demo.* 64 | 65 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "examples/tui/linenoise"] 2 | path = examples/tui/linenoise 3 | url = https://github.com/antirez/linenoise 4 | [submodule "examples/tui/jquery.terminal"] 5 | path = examples/tui/jquery.terminal 6 | url = https://github.com/jcubic/jquery.terminal 7 | [submodule "tests/googletest"] 8 | path = tests/googletest 9 | url = https://github.com/google/googletest 10 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.11) 2 | project (limbo) 3 | 4 | include (CTest) 5 | 6 | #set (CMAKE_BUILD_TYPE Release) 7 | set (CMAKE_BUILD_TYPE Debug) 8 | 9 | set (CMAKE_VERBOSE_MAKEFILE ON) 10 | 11 | # Good for YCM-Generator for the Vim YouCompleteMe plugin 12 | set (CMAKE_EXPORT_COMPILE_COMMANDS ON) 13 | 14 | set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") 15 | 16 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -march=native") 17 | if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 18 | #set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") 19 | endif () 20 | 21 | if (CMAKE_CXX_COMPILER_ID MATCHES "(Clang|GNU)") 22 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wuninitialized -pedantic -Wno-zero-length-array") 23 | endif () 24 | 25 | # Debug configuration 26 | if (CMAKE_BUILD_TYPE MATCHES Debug) 27 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") 28 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LIBCPP_DEBUG") 29 | #set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_CONCEPT_CHECKS") 30 | # defining 31 | # -D_GLIBCXX_CONCEPT_CHECKS 32 | # leads to compiler errors when using things like 33 | # std::vector> asdf; 34 | # because of missing copy assignment operators 35 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC") 36 | endif () 37 | #set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNDEBUG") 38 | 39 | # Release configuration 40 | if (CMAKE_BUILD_TYPE MATCHES Release) 41 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 42 | endif () 43 | 44 | add_subdirectory (src) 45 | add_subdirectory (tests) 46 | add_subdirectory (examples) 47 | 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2019 Christoph Schwering 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /cmake/FindEmscripten.cmake: -------------------------------------------------------------------------------- 1 | FIND_PROGRAM (EMCC em++) 2 | 3 | IF (EMCC) 4 | MESSAGE(STATUS "Searching Emscripten - found") 5 | #MESSAGE(STATUS ${EMCC}) 6 | ELSE() 7 | MESSAGE(STATUS "Searching Emscripten - not found") 8 | ENDIF() 9 | 10 | 11 | -------------------------------------------------------------------------------- /cpplint: -------------------------------------------------------------------------------- 1 | if [ ! -f cpplint.py ] 2 | then 3 | wget https://raw.githubusercontent.com/google/styleguide/gh-pages/cpplint/cpplint.py 4 | chmod +x cpplint.py 5 | fi 6 | 7 | #if [ "$(which cppclean)" == "" ] 8 | #then 9 | # sudo pip install --upgrade cppclean 10 | #fi 11 | 12 | ./cpplint.py --root=src --filter=-build/include_order --linelength=120 $(find src/ -name \*.h -or -name \*.cc) 13 | #cppclean --include=src src 14 | 15 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory (minesweeper) 2 | add_subdirectory (sat) 3 | add_subdirectory (sudoku) 4 | add_subdirectory (tui) 5 | 6 | -------------------------------------------------------------------------------- /examples/jquery.sh: -------------------------------------------------------------------------------- 1 | wget -O "jquery-3.1.1.min.js" "https://code.jquery.com/jquery-3.1.1.min.js" 2 | 3 | -------------------------------------------------------------------------------- /examples/minesweeper/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable (minesweeper minesweeper.cc) 2 | target_link_libraries (minesweeper LINK_PUBLIC limbo) 3 | 4 | #set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_DETERMINES") 5 | #set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEND_GAME_CLAUSES") 6 | 7 | find_package (Emscripten) 8 | if (EMCC) 9 | if (CMAKE_BUILD_TYPE MATCHES Release) 10 | separate_arguments(FLAGS UNIX_COMMAND "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") 11 | add_custom_command (OUTPUT minesweeper-js.js minesweeper-js.js.mem 12 | COMMAND ${EMCC} ${FLAGS} -I../../src minesweeper-js.cc -o minesweeper-js.js 13 | -s EXPORTED_FUNCTIONS=['_limbo_init','_limbo_play_turn'] 14 | -s TOTAL_MEMORY=67108864 15 | DEPENDS minesweeper-js.cc "*.h" 16 | VERBATIM) 17 | 18 | add_custom_target (minesweeper-js DEPENDS minesweeper-js.js minesweeper-js.js.mem) 19 | add_dependencies (minesweeper minesweeper-js) 20 | endif () 21 | endif () 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/minesweeper/agent.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2014 Christoph Schwering 3 | 4 | #ifndef EXAMPLES_MINESWEEPER_AGENT_H_ 5 | #define EXAMPLES_MINESWEEPER_AGENT_H_ 6 | 7 | #include 8 | #include 9 | 10 | #include "game.h" 11 | #include "kb.h" 12 | 13 | template 14 | class Agent { 15 | public: 16 | explicit Agent(Game* g, KnowledgeBase* kb, Logger logger = Logger()) : g_(g), kb_(kb), logger_(logger) {} 17 | 18 | int Explore() { 19 | kb_->Sync(); 20 | 21 | // First open a random point which is not at the edge of the field. 22 | if (g_->n_opens() == 0) { 23 | Point p; 24 | do { 25 | p = g_->RandomPoint(); 26 | } while (g_->neighbors_of(p).size() < 8); 27 | logger_.explored(p, -1); 28 | g_->OpenWithFrontier(p); 29 | last_point_ = p; 30 | return -1; 31 | } 32 | 33 | // First look for a field which is known not to be a mine. 34 | for (size_t k = 0; k <= kb_->max_k(); ++k) { 35 | std::vector inspected(g_->n_fields(), false); 36 | const std::size_t max_radius = std::max(std::max(last_point_.x, g_->width() - last_point_.x), 37 | std::max(last_point_.y, g_->height() - last_point_.y)); 38 | for (std::size_t radius = 0; radius <= max_radius; ++radius) { 39 | std::vector on_rectangle = Rectangle(last_point_, radius); 40 | for (std::size_t i = 0; i < g_->n_fields(); ++i) { 41 | if (inspected[i] || !on_rectangle[i]) { 42 | continue; 43 | } 44 | const Point p = g_->to_point(i); 45 | if (g_->opened(p) || g_->flagged(p)) { 46 | continue; 47 | } 48 | const limbo::internal::Maybe r = kb_->IsMine(p, k); 49 | if (r.yes) { 50 | if (r.val) { 51 | logger_.flagged(p, k); 52 | g_->Flag(p); 53 | } else { 54 | logger_.explored(p, k); 55 | g_->OpenWithFrontier(p); 56 | } 57 | last_point_ = p; 58 | return k; 59 | } 60 | inspected[i] = true; 61 | } 62 | } 63 | } 64 | 65 | // Didn't find any reliable action, so we need to guess. Non-frontier cells are preferred. 66 | for (std::size_t i = 0; i < g_->n_fields(); ++i) { 67 | const Point p = g_->to_point(i); 68 | if (g_->opened(p) || g_->flagged(p) || g_->frontier(p)) { 69 | continue; 70 | } 71 | logger_.explored(p, -1); 72 | g_->OpenWithFrontier(p); 73 | last_point_ = p; 74 | return kb_->max_k() + 1; 75 | } 76 | for (std::size_t i = 0; i < g_->n_fields(); ++i) { 77 | const Point p = g_->to_point(i); 78 | if (g_->opened(p) || g_->flagged(p)) { 79 | continue; 80 | } 81 | logger_.explored(p, -1); 82 | g_->OpenWithFrontier(p); 83 | last_point_ = p; 84 | return kb_->max_k() + 1; 85 | } 86 | 87 | // That's weird, this case should never occur, because our reasoning should 88 | // be correct. 89 | std::cerr << __FILE__ << ":" << __LINE__ << ": Why didn't we choose a point?" << std::endl; 90 | assert(false); 91 | return -2; 92 | } 93 | 94 | Logger& logger() { return logger_; } 95 | const Logger& logger() const { return logger_; } 96 | 97 | private: 98 | std::vector Rectangle(Point p, int radius) { 99 | const int x0 = p.x; 100 | const int y0 = p.y; 101 | std::vector rectangle(g_->n_fields()); 102 | for (int x = -radius; x <= radius; ++x) { 103 | set_rectangle(&rectangle, x0 + x, y0 + radius); 104 | set_rectangle(&rectangle, x0 + x, y0 - radius); 105 | } 106 | for (int y = -radius; y <= radius; ++y) { 107 | set_rectangle(&rectangle, x0 + radius, y0 - y); 108 | set_rectangle(&rectangle, x0 - radius, y0 - y); 109 | } 110 | return rectangle; 111 | } 112 | 113 | void set_rectangle(std::vector* rectangle, int x, int y) { 114 | if (0 <= x && x < static_cast(g_->width()) && 0 <= y && y < static_cast(g_->height())) { 115 | (*rectangle)[g_->to_index(Point(x, y))] = true; 116 | } 117 | } 118 | 119 | Game* g_; 120 | KnowledgeBase* kb_; 121 | Logger logger_; 122 | Point last_point_; 123 | }; 124 | 125 | #endif // EXAMPLES_MINESWEEPER_AGENT_H_ 126 | 127 | -------------------------------------------------------------------------------- /examples/minesweeper/eval.sh: -------------------------------------------------------------------------------- 1 | for F in "$@" 2 | do 3 | echo "File: $F" 4 | 5 | echo -n "Solved: " 6 | 7 | N=$(grep -v '^#' $F | grep "You" | wc -l) 8 | 9 | python -c "print '%d / %d = %f' % ( $(grep -v '^#' $F | grep "You" | grep win | wc -l), $N, $(grep -v '^#' $F | grep "You" | grep win | wc -l).0 / $N )" 10 | 11 | echo -n "Average time (seconds): " 12 | python -c "print $((grep -v '^#' $F | grep "You" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | sed -e 's/^.\+runtime://g' | sed -e 's/seconds.\+$//g' && echo 0.0) | paste -sd+ | bc) / $N" 13 | 14 | # echo -n "Average time per move (seconds): " 15 | # python -c "print '%.2E' % ($((grep -v '^#' $F | grep "Last move" | sed -e "s/^[^0-9]\+//g" | sed -e 's/,.\+//g' && echo 0.0) | paste -sd+ | bc) / $(grep -v '^#' $F | grep "Last move" | wc -l))" 16 | # 17 | # echo -n "Found at level 0 (avg per game): " 18 | # python -c "print $(grep -v '^#' $F | grep "level 0: " | wc -l).0 / $N" 19 | # 20 | # echo -n "Found at level 1 (avg per game): " 21 | # python -c "print $(grep -v '^#' $F | grep "level 1: " | wc -l).0 / $N" 22 | # 23 | # echo -n "Found at level 2 (avg per game): " 24 | # python -c "print $(grep -v '^#' $F | grep "level 2: " | wc -l).0 / $N" 25 | # 26 | # echo -n "Found at level 3 (avg per game): " 27 | # python -c "print $(grep -v '^#' $F | grep "level 3: " | wc -l).0 / $N" 28 | # 29 | # echo -n "Found at level >0 (avg per game): " 30 | # python -c "print $(grep -v '^#' $F | grep -v "level 0: " | wc -l).0 / $N" 31 | # 32 | # echo -n "Guesses (avg per game): " 33 | # python -c "print $(grep -v '^#' $F | grep "guess" | wc -l).0 / $N" 34 | 35 | echo "" 36 | done 37 | 38 | -------------------------------------------------------------------------------- /examples/minesweeper/flag.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | Red Flag 25 | 26 | 27 | 28 | 30 | 54 | Red Flag 56 | 59 | Layer 1 61 | 63 | 69 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /examples/minesweeper/loop.sh: -------------------------------------------------------------------------------- 1 | max=$1 2 | maxk=$2 3 | for seed in $(seq 1 $max); do ./mw 16 16 40 $seed $maxk; done 4 | 5 | -------------------------------------------------------------------------------- /examples/minesweeper/minesweeper-js.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2016 Christoph Schwering 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "agent.h" 10 | #include "game.h" 11 | #include "kb.h" 12 | #include "printer.h" 13 | #include "timer.h" 14 | 15 | namespace game { 16 | 17 | struct Logger { 18 | void explored(Point p, int k) const { 19 | EM_ASM_({ 20 | updateMessage(0, $0, $1, $2); 21 | }, p.x, p.y, k); 22 | } 23 | 24 | void flagged(Point p, int k) const { 25 | EM_ASM_({ 26 | updateMessage(1, $0, $1, $2); 27 | }, p.x, p.y, k); 28 | } 29 | }; 30 | 31 | static Game* game = nullptr; 32 | static KnowledgeBase* kb = nullptr; 33 | static Agent* agent = nullptr; 34 | static Timer* timer_overall = nullptr; 35 | static std::vector* split_counts = nullptr; 36 | 37 | void Finalize() { 38 | limbo::Symbol::Factory::Reset(); 39 | limbo::Term::Factory::Reset(); 40 | if (game) 41 | delete game; 42 | if (kb) 43 | delete kb; 44 | if (agent) 45 | delete agent; 46 | if (timer_overall) 47 | delete timer_overall; 48 | if (split_counts) 49 | delete split_counts; 50 | } 51 | 52 | void Init(size_t width, size_t height, size_t n_mines, size_t seed, size_t max_k) { 53 | Finalize(); 54 | game = new Game(width, height, n_mines, seed); 55 | kb = new KnowledgeBase(game, max_k); 56 | timer_overall = new Timer(); 57 | agent = new Agent(game, kb); 58 | split_counts = new std::vector(); 59 | split_counts->resize(max_k + 2); // last one is for guesses 60 | } 61 | 62 | void DisplayGame(const Game& g, bool omniscient = false) { 63 | std::stringstream ss; 64 | if (!omniscient) { 65 | SimplePrinter(&ss).Print(*game); 66 | } else { 67 | OmniscientPrinter(&ss).Print(*game); 68 | } 69 | EM_ASM_({ 70 | if ($1) { 71 | updateMessageGameOver(); 72 | } 73 | displayGame(Pointer_stringify($0)); 74 | }, ss.str().c_str(), omniscient); 75 | } 76 | 77 | bool PlayTurn() { 78 | timer_overall->start(); 79 | const int k = agent->Explore(); 80 | timer_overall->stop(); 81 | if (k >= 0) { 82 | ++(*split_counts)[k]; 83 | } 84 | DisplayGame(*game); 85 | const bool game_over = game->hit_mine() || game->all_explored(); 86 | if (game_over) { 87 | DisplayGame(*game, true); 88 | } 89 | return game_over; 90 | } 91 | 92 | } // namespace game 93 | 94 | extern "C" void limbo_init(size_t width, size_t height, size_t n_mines, size_t seed, int max_k) { 95 | game::Init(width, height, n_mines, seed, max_k); 96 | } 97 | 98 | extern "C" int limbo_play_turn() { 99 | return game::PlayTurn() ? 1 : 0; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /examples/minesweeper/minesweeper.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2014 Christoph Schwering 3 | // 4 | // Command line application that plays minesweeper. 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "agent.h" 12 | #include "game.h" 13 | #include "kb.h" 14 | #include "printer.h" 15 | #include "timer.h" 16 | 17 | struct Logger { 18 | void explored(Point p, int k) const { 19 | std::cout << "Exploring"; 20 | Rest(p, k); 21 | } 22 | 23 | void flagged(Point p, int k) const { 24 | std::cout << "Flagging"; 25 | Rest(p, k); 26 | } 27 | 28 | private: 29 | void Rest(Point p, int k) const { 30 | std::cout << " " << Point(p.x+1, p.y+1); 31 | if (first_ && k == -1) { 32 | std::cout << ", chosen at random."; 33 | } else if (k == -1) { 34 | using limbo::format::operator<<; 35 | std::cout << ", which is just a guess."; 36 | } else { 37 | std::cout << ", found at split level " << k << "."; 38 | } 39 | first_ = false; 40 | } 41 | 42 | mutable bool first_ = false; 43 | }; 44 | 45 | inline bool Play(size_t width, size_t height, size_t n_mines, size_t seed, size_t max_k, 46 | const Colors& colors, std::ostream* os) { 47 | Timer overall_timer; 48 | Game g(width, height, n_mines, seed); 49 | KnowledgeBase kb(&g, max_k); 50 | Agent agent(&g, &kb); 51 | SimplePrinter printer(&colors, os); 52 | OmniscientPrinter final_printer(&colors, os); 53 | std::vector split_counts; 54 | split_counts.resize(max_k + 2); // last one is for guesses 55 | do { 56 | Timer turn_timer; 57 | turn_timer.start(); 58 | overall_timer.start(); 59 | const int k = agent.Explore(); 60 | overall_timer.stop(); 61 | turn_timer.stop(); 62 | if (k >= 0) { 63 | ++split_counts[k]; 64 | } 65 | *os << std::endl; 66 | printer.Print(g); 67 | *os << std::endl; 68 | *os << "Last move took " << std::fixed << turn_timer.duration() << ", queries took " << std::fixed << kb.timer().duration() << " / " << std::setw(4) << kb.timer().rounds() << " = " << std::fixed << kb.timer().avg_duration() << std::endl; 69 | kb.ResetTimer(); 70 | } while (!g.hit_mine() && !g.all_explored()); 71 | *os << "Final board:" << std::endl; 72 | *os << std::endl; 73 | final_printer.Print(g); 74 | *os << std::endl; 75 | const bool win = !g.hit_mine(); 76 | if (win) { 77 | *os << colors.green() << "You win :-)"; 78 | } else { 79 | *os << colors.red() << "You loose :-("; 80 | } 81 | *os << " [width: " << g.width() << "; height: " << g.height() << "; height: " << g.n_mines() << "; seed: " << g.seed() << "; max-k: " << max_k << "; "; 82 | for (size_t k = 0; k < split_counts.size(); ++k) { 83 | const int n = split_counts[k]; 84 | if (n > 0) { 85 | if (k == max_k + 1) { 86 | std::cout << "guesses: " << n << "; "; 87 | } else { 88 | std::cout << "level " << k << ": " << n << "; "; 89 | } 90 | } 91 | } 92 | *os << "runtime: " << overall_timer.duration() << " seconds]" << colors.reset() << std::endl; 93 | return win; 94 | } 95 | 96 | int main(int argc, char *argv[]) { 97 | size_t width = 8; 98 | size_t height = 8; 99 | size_t n_mines = 10; 100 | size_t seed = 0; 101 | size_t max_k = 2; 102 | if (argc >= 2) { 103 | width = atoi(argv[1]); 104 | } 105 | if (argc >= 3) { 106 | height = atoi(argv[2]); 107 | } 108 | n_mines = (width + 1) * (height + 1) / 10; 109 | if (argc >= 4) { 110 | n_mines = atoi(argv[3]); 111 | } 112 | if (argc >= 5) { 113 | seed = atoi(argv[4]); 114 | } 115 | if (argc >= 6) { 116 | max_k = atoi(argv[5]); 117 | } 118 | Play(width, height, n_mines, seed, max_k, TerminalColors(), &std::cout); 119 | return 0; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /examples/minesweeper/test.sh: -------------------------------------------------------------------------------- 1 | W=$1 2 | H=$2 3 | M=$3 4 | K=$4 5 | max=$5 6 | F=test-${W}x${H}-${M}-${K}-${max}.log 7 | 8 | inxi -Fx -c 0 >$F 9 | 10 | for seed in $(seq 1 $max); do ./minesweeper $W $H $M $seed $K | grep You >>$F; done 11 | echo $F 12 | 13 | -------------------------------------------------------------------------------- /examples/minesweeper/timer.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2014 Christoph Schwering 3 | 4 | #ifndef EXAMPLES_MINESWEEPER_TIMER_H_ 5 | #define EXAMPLES_MINESWEEPER_TIMER_H_ 6 | 7 | #include 8 | 9 | class Timer { 10 | public: 11 | Timer() : start_(std::clock()) {} 12 | 13 | void start() { 14 | start_ = std::clock() - (end_ != 0 ? end_ - start_ : 0); 15 | ++rounds_; 16 | } 17 | void stop() { end_ = std::clock(); } 18 | void reset() { start_ = 0; end_ = 0; rounds_ = 0; } 19 | 20 | double duration() const { return (end_ - start_) / (double) CLOCKS_PER_SEC; } 21 | size_t rounds() const { return rounds_; } 22 | double avg_duration() const { return duration() / rounds_; } 23 | 24 | private: 25 | std::clock_t start_; 26 | std::clock_t end_ = 0; 27 | size_t rounds_ = 0; 28 | }; 29 | 30 | #endif // EXAMPLES_MINESWEEPER_TIMER_H_ 31 | 32 | -------------------------------------------------------------------------------- /examples/sat/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable (sat sat.cc) 2 | target_link_libraries (sat LINK_PUBLIC limbo) 3 | 4 | add_executable (limsat limsat.cc) 5 | target_link_libraries (limsat LINK_PUBLIC limbo) 6 | 7 | -------------------------------------------------------------------------------- /examples/sat/pigeonhole.c: -------------------------------------------------------------------------------- 1 | // **************************************************************************** 2 | // A small C program to create DIMACS CNF files that encode the pigeonhole 3 | // problem (i.e. placing n+1 pigeons into n holes). 4 | // 5 | // The SAT encoding of this problem is very straightforward. For each pigeon i 6 | // and each hole j we have a variable x_{n*(i-1)+j} which means that pigeon i 7 | // is placed in hole j. Then we have n+1 clauses which say that a pigeon has 8 | // to be placed in some hole. Then for each hole we have a set of clauses 9 | // ensuring that only one single pigeon is placed into that hole. 10 | // 11 | // This encoding leads to a total of (n+1) * n propositional variables and 12 | // (n+1) + n * (n * (n+1) / 2) clauses. 13 | // 14 | // The resulting SAT problem is unsatisfiable. 15 | // 16 | // Version 1.0, 2007-03-15 17 | // (c) 2007 Tjark Weber 18 | // 19 | // I've added output for functional SAT. -- Christoph Schwering 20 | // **************************************************************************** 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | void usage() { 28 | printf("Usage:\n"); 29 | printf("\n"); 30 | printf(" pigeonhole n\n"); 31 | printf("\n"); 32 | printf("where n>0 is the number of holes (the number of pigeons is n+1).\n"); 33 | exit(1); 34 | } 35 | 36 | int main(int argc, char** argv) { 37 | 38 | int n; // n+1 pigeons in n holes 39 | 40 | int i, k; // pigeons i, k 41 | int j; // hole j 42 | 43 | bool prop = true; 44 | 45 | if (argc <= 1) 46 | usage(); 47 | 48 | for (i = 0; i < argc; ++i) { 49 | if (sscanf(argv[i], "%d", &n) == 1) { 50 | } else if (!strcmp(argv[i], "cnf")) { 51 | prop = true; 52 | } else if (!strcmp(argv[i], "fcnf")) { 53 | prop = false; 54 | } 55 | } 56 | 57 | if (n < 1) 58 | usage(); 59 | 60 | // DIMACS header 61 | #if 0 62 | printf("c pigeon-%d: placing %d pigeons into %d holes\n", n, n+1, n); 63 | printf("c %s version\n", prop ? "propositional" : "functional"); 64 | printf("c \n"); 65 | printf("c File generated by 'pigeonhole', (c) Tjark Weber\n"); 66 | printf("c \n"); 67 | if (prop) { 68 | printf("c The propositional SAT encoding of this problem is very straightforward.\n"); 69 | printf("c For each pigeon i and each hole j we have a variable x_{n*(i-1)+j} which\n"); 70 | printf("c means that pigeon ic is placed in hole j. Then we have n+1 clauses which\n"); 71 | printf("c say that a pigeon has to be placed in one of the n holes. Then for each\n"); 72 | printf("c hole we have a set of clauses ensuring that only one single pigeon is\n"); 73 | printf("c placed into that hole.\n"); 74 | } else { 75 | printf("c The functional SAT encoding of this problem is very straightforward.\n"); 76 | printf("c For each pigeon i we use a function that maps to a hole the pigeon is in.\n"); 77 | printf("c Then we have n+1 clauses which say that a pigeon has to be placed in one\n"); 78 | printf("c of the n holes. Then for pair of pigeons we have n clauses saying that the\n"); 79 | printf("c two pigeons cannot be in the same hole.\n"); 80 | printf("c \n"); 81 | } 82 | printf("c \n"); 83 | printf("c This encoding leads to a total of (n+1) * n propositional variables and\n"); 84 | printf("c (n+1) + n * (n * (n+1) / 2) clauses.\n"); 85 | printf("c \n"); 86 | printf("c The resulting SAT problem is unsatisfiable.\n"); 87 | printf("c \n"); 88 | #endif 89 | if (prop) { 90 | printf("p cnf %d %d\n", (n+1) * n, (n+1) + n * (n * (n+1) / 2)); 91 | 92 | // n+1 clauses which say that a pigeon has to be placed in some hole 93 | for (i=1; i <= n+1; i++) { 94 | for (j=1; j <= n; j++) 95 | printf("%d ", n*(i-1)+j); 96 | printf("0\n"); 97 | } 98 | 99 | // for each hole we have a set of clauses ensuring that only one single 100 | // pigeon is placed into that hole 101 | for (j=1; j <= n; j++) 102 | for (i=1; i <= n; i++) 103 | for (k=i+1; k <= n+1; k++) 104 | printf("-%d -%d 0\n", n*(i-1)+j, n*(k-1)+j); 105 | } else { 106 | printf("p fcnf %d %d %d\n", (n+1), n, (n+1) + n * (n * (n+1) / 2)); 107 | 108 | 109 | // n+1 clauses, each of which says that one specific pigeon must be in 110 | // one of the holes 111 | for (i=1; i <= n+1; i++) { 112 | for (j=1; j <= n; j++) 113 | printf("%3d = %2d ", i, j); 114 | printf("0\n"); 115 | } 116 | 117 | // no two pigeons must go into the same hole 118 | for (j=1; j <= n; j++) 119 | for (i=1; i <= n+1; i++) 120 | for (k=i+1; k <= n+1; k++) 121 | printf("%3d = %2d %3d = %2d 0\n", -i, j, -k, j); 122 | } 123 | 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /examples/sat/pigeons.sh: -------------------------------------------------------------------------------- 1 | #echo "Limbo / propositional" 2 | #for i in $(seq 1 9); do f=pigeons/cnf-$i; echo -n "$f: " && cat $f | ./sat | grep -i satisfiable; done 3 | echo "Limbo / propositional functionalized" 4 | for i in $(seq 1 9); do f=pigeons/cnf-$i; echo -n "$f: " && cat $f | ./functionalize | ./sat | grep -i satisfiable; done 5 | echo "Limbo / functional" 6 | for i in $(seq 1 11); do f=pigeons/fcnf-$i; echo -n "$f: " && cat $f | ./sat | grep -i satisfiable; done 7 | echo "sat-cdcl / propositional" 8 | for i in $(seq 1 11); do f=pigeons/cnf-$i; echo -n "$f: " && ../../../2017-08-COMP4418/SAT/sat-cdcl $f | grep -i satisfiable; done 9 | echo "MiniSAT / propositional" 10 | for i in $(seq 1 11); do f=pigeons/cnf-$i; echo -n "$f: " && cat $f | ../../../Spielplatz/minisat/minisat | grep -i satisfiable; done 11 | 12 | -------------------------------------------------------------------------------- /examples/sat/sudoku2cnf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | 5 | def to_index(x, y = None): 6 | if isinstance(x, tuple): 7 | (x,y) = x 8 | return x + (y - 1) * 9; 9 | 10 | def to_point(i): 11 | x = ((i-1) % 9) + 1 12 | y = ((i-1) // 9) + 1 13 | return (x,y) 14 | 15 | def prop(x, y, v = None): 16 | i = None 17 | if isinstance(x, tuple): 18 | v = y 19 | (x,y) = x 20 | i = to_index(x, y) 21 | elif v is None: 22 | v = y 23 | i = x 24 | else: 25 | i = to_index(x, y) 26 | return (1 if i >= 0 else -1) * ((abs(i) - 1) * 9 + v) 27 | 28 | 29 | sudoku = sys.argv[1] 30 | 31 | fcs = set() 32 | 33 | # Clues 34 | for i in range(0, len(sudoku)): 35 | if '1' <= sudoku[i] <= '9': 36 | v = ord(sudoku[i]) - ord('0') 37 | fc = frozenset([(i+1, v)]) 38 | fcs.add(fc) 39 | 40 | # Sudoku rule: every cell has value 1..9 41 | for x in range(1,10): 42 | for y in range(1,10): 43 | fc = frozenset([(to_index(x,y),v) for v in range(1, 10)]) 44 | fcs.add(fc) 45 | 46 | # Sudoku rule: in every column, no two cells have the same value 47 | for x in range(1, 10): 48 | for xx in range(1, x): 49 | for y in range(1, 10): 50 | for v in range(1, 10): 51 | fc = frozenset([(-to_index(x,y),v), (-to_index(xx,y),v)]) 52 | fcs.add(fc) 53 | 54 | # Sudoku rule: in every row, no two cells have the same value 55 | for x in range(1, 10): 56 | for y in range(1, 10): 57 | for yy in range(1, y): 58 | for v in range(1, 10): 59 | fc = frozenset([(-to_index(x,y),v), (-to_index(x,yy),v)]) 60 | fcs.add(fc) 61 | 62 | # Sudoku rule: in every box, no two cells have the same value 63 | for i in range(1,4): 64 | for j in range(1,4): 65 | for x in range(3*i-2, 3*i+1): 66 | for xx in range(3*i-2, 3*i+1): 67 | for y in range(3*j-2, 3*j+1): 68 | for yy in range(3*j-2, 3*j+1): 69 | if (x,y) != (xx,yy): 70 | for v in range(1, 10): 71 | fc = frozenset([(-to_index(x,y),v), (-to_index(xx,yy),v)]) 72 | fcs.add(fc) 73 | 74 | cs = set() 75 | 76 | for fc in fcs: 77 | c = frozenset([prop(i,v) for (i,v) in fc]) 78 | cs.add(c) 79 | 80 | for x in range(1,10): 81 | for y in range(1,10): 82 | c = frozenset([prop(x,y,v) for v in range(1,10)]) 83 | cs.add(c) 84 | for v in range(1,10): 85 | for vv in range(1,v): 86 | c = frozenset([-prop(x,y,v), -prop(x,y,vv)]) 87 | cs.add(c) 88 | 89 | print("p cnf %d %d" % (81 * 9, len(cs))) 90 | for c in sorted(cs, key=len): 91 | for p in c: 92 | print("%4d " % (p,), end='') 93 | print("%d" % (0,)) 94 | 95 | -------------------------------------------------------------------------------- /examples/sat/sudoku2fcnf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | 5 | def to_index(x,y = None): 6 | if isinstance(x, tuple): 7 | (x,y) = x 8 | return x + (y - 1) * 9; 9 | 10 | def to_point(i): 11 | x = ((i-1) % 9) + 1 12 | y = ((i-1) // 9) + 1 13 | return (x,y) 14 | 15 | sudoku = sys.argv[1] 16 | 17 | fcs = set() 18 | 19 | # Clues 20 | for i in range(0, len(sudoku)): 21 | if '1' <= sudoku[i] <= '9': 22 | v = ord(sudoku[i]) - ord('0') 23 | fc = frozenset([(i+1, v)]) 24 | fcs.add(fc) 25 | 26 | # Sudoku rule: every cell has value 1..9 27 | for x in range(1,10): 28 | for y in range(1,10): 29 | fc = frozenset([(to_index(x,y),v) for v in range(1, 10)]) 30 | fcs.add(fc) 31 | 32 | # Sudoku rule: in every column, no two cells have the same value 33 | for x in range(1, 10): 34 | for xx in range(1, x): 35 | for y in range(1, 10): 36 | for v in range(1, 10): 37 | fc = frozenset([(-to_index(x,y),v), (-to_index(xx,y),v)]) 38 | fcs.add(fc) 39 | 40 | # Sudoku rule: in every row, no two cells have the same value 41 | for x in range(1, 10): 42 | for y in range(1, 10): 43 | for yy in range(1, y): 44 | for v in range(1, 10): 45 | fc = frozenset([(-to_index(x,y),v), (-to_index(x,yy),v)]) 46 | fcs.add(fc) 47 | 48 | # Sudoku rule: in every box, no two cells have the same value 49 | for i in range(1,4): 50 | for j in range(1,4): 51 | for x in range(3*i-2, 3*i+1): 52 | for xx in range(3*i-2, 3*i+1): 53 | for y in range(3*j-2, 3*j+1): 54 | for yy in range(3*j-2, 3*j+1): 55 | if (x,y) != (xx,yy): 56 | for v in range(1, 10): 57 | fc = frozenset([(-to_index(x,y),v), (-to_index(xx,yy),v)]) 58 | fcs.add(fc) 59 | 60 | 61 | print("p fcnf %d %d %d" % (81, 9, len(fcs))) 62 | for fc in sorted(fcs, key=len): 63 | for (lhs,rhs) in fc: 64 | print("%3d = %1d " % (lhs,rhs), end='') 65 | print("%d" % (0,)) 66 | 67 | -------------------------------------------------------------------------------- /examples/sat/sudokus.sh: -------------------------------------------------------------------------------- 1 | F=sudokus 2 | if [ "$1" != "" ] 3 | then 4 | F=$1 5 | fi 6 | echo "Limbo / functional" 7 | for f in $(ls -a1 $F | grep '^fcnf'); do cat $F/$f | ./sat -e=0 -c=1 | grep -i satisfiable; done | ./sum.sh 8 | echo "Limbo / propositional" 9 | for f in $(ls -a1 $F | grep '^cnf'); do cat $F/$f | ./sat -e=0 -c=1 | grep -i satisfiable; done | ./sum.sh 10 | #echo "sat-cdcl / propositional" 11 | #for f in $(ls -a1 $F | grep '\.cnf'); do ../../../2017-08-COMP4418/SAT/sat-cdcl $F/$f | grep -i satisfiable; done | ./sum.sh 12 | #echo "MiniSAT / propositional" 13 | #for f in $(ls -a1 $F | grep '\.cnf'); do cat $F/$f | ../../../Spielplatz/minisat/minisat | grep -i satisfiable; done | ./sum.sh 14 | 15 | -------------------------------------------------------------------------------- /examples/sat/sum.sh: -------------------------------------------------------------------------------- 1 | sed -ue 's/.\+(in //g' | \ 2 | sed -ue 's/s)//g' | \ 3 | sed -ue 's/s, sat-cdcl)//g' | \ 4 | python3 -c " 5 | import sys 6 | sum = 0 7 | cnt = 0 8 | min = -1 9 | mini = -1 10 | max = -1 11 | maxi = -1 12 | for line in sys.stdin: 13 | f = float(line.strip()) 14 | sum = sum + f 15 | cnt = cnt + 1 16 | if min < 0 or min > f: 17 | min = f 18 | mini = cnt 19 | if max < 0 or max < f: 20 | max = f 21 | maxi = cnt 22 | print('%.5f / %4d = %.5f | min = %.5f (%d) | max = %.5f (%d)' % (sum, cnt, sum/cnt, min, mini, max, maxi), flush=True, end='\r') 23 | print('') 24 | " 25 | 26 | -------------------------------------------------------------------------------- /examples/sat/update.sh: -------------------------------------------------------------------------------- 1 | while read line 2 | do 3 | echo -en "$line\r" 4 | done 5 | echo "" 6 | 7 | -------------------------------------------------------------------------------- /examples/sat/vg.sh: -------------------------------------------------------------------------------- 1 | valgrind --tool=callgrind "$@" && mv callgrind.out.* cg$(expr $(ls -1 cg* | wc -l) + 1) 2 | 3 | -------------------------------------------------------------------------------- /examples/sudoku/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable (sudoku sudoku.cc) 2 | target_link_libraries (sudoku LINK_PUBLIC limbo) 3 | 4 | 5 | # add_test (NAME sudokus COMMAND ./test-sudokus.sh) 6 | 7 | 8 | #find_package (Emscripten) 9 | #if (EMCC) 10 | # if (CMAKE_BUILD_TYPE MATCHES Release) 11 | # separate_arguments(FLAGS UNIX_COMMAND "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") 12 | # add_custom_command (OUTPUT sudoku-js.js sudoku-js.js.mem 13 | # COMMAND ${EMCC} ${FLAGS} -I../../src sudoku-js.cc -o sudoku-js.js 14 | # -s EXPORTED_FUNCTIONS=['_limbo_init','_limbo_play_turn'] 15 | # -s TOTAL_MEMORY=67108864 16 | # DEPENDS sudoku-js.cc "*.h" 17 | # VERBATIM) 18 | # 19 | # add_custom_target (sudoku-js DEPENDS sudoku-js.js sudoku-js.js.mem) 20 | # add_dependencies (sudoku sudoku-js) 21 | # endif () 22 | #endif () 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/sudoku/agent.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2017 Christoph Schwering 3 | 4 | #ifndef EXAMPLES_SUDOKU_AGENT_H_ 5 | #define EXAMPLES_SUDOKU_AGENT_H_ 6 | 7 | #include 8 | 9 | #include 10 | 11 | #include "game.h" 12 | #include "kb.h" 13 | 14 | class Agent { 15 | public: 16 | struct Result { 17 | Result() = default; 18 | Result(Point p, int n, int k) : p(p), n(n), k(k) {} 19 | Point p; 20 | int n; 21 | int k; 22 | }; 23 | 24 | virtual ~Agent() {} 25 | virtual limbo::internal::Maybe Explore() = 0; 26 | }; 27 | 28 | class KnowledgeBaseAgent : public Agent { 29 | public: 30 | explicit KnowledgeBaseAgent(Game* g, KnowledgeBase* kb) : g_(g), kb_(kb) {} 31 | 32 | limbo::internal::Maybe Explore() override { 33 | for (int k = 0; k <= kb_->max_k(); ++k) { 34 | for (int y = 1; y <= 9; ++y) { 35 | for (int x = 1; x <= 9; ++x) { 36 | Point p(x, y); 37 | if (g_->get(p) == 0) { 38 | const limbo::internal::Maybe r = kb_->Val(p, k); 39 | if (r) { 40 | const int n = r.val; 41 | kb_->Add(p, n); 42 | g_->set(p, n); 43 | return limbo::internal::Just(Result(p, n, k)); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | return limbo::internal::Nothing; 50 | } 51 | 52 | private: 53 | Game* g_; 54 | KnowledgeBase* kb_; 55 | }; 56 | 57 | #endif // EXAMPLES_SUDOKU_AGENT_H_ 58 | 59 | -------------------------------------------------------------------------------- /examples/sudoku/game.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2017 Christoph Schwering 3 | 4 | #ifndef EXAMPLES_SUDOKU_GAME_H_ 5 | #define EXAMPLES_SUDOKU_GAME_H_ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | struct Point { 18 | Point() {} 19 | Point(int x, int y) : x(x), y(y) {} 20 | 21 | bool operator<(const Point& p) const { 22 | return x < p.x || (x == p.x && y < p.y); 23 | } 24 | 25 | bool operator==(const Point& p) const { 26 | return x == p.x && y == p.y; 27 | } 28 | 29 | int x; 30 | int y; 31 | }; 32 | 33 | std::ostream& operator<<(std::ostream& os, const Point& p) { 34 | return os << "(" << p.x << " | " << p.y << ")"; 35 | } 36 | 37 | 38 | class Game { 39 | public: 40 | explicit Game(const std::string& cfg) { 41 | for (int i = 0; i < 9*9; ++i) { 42 | const char c = i < static_cast(cfg.length()) ? cfg.at(i) : 0; 43 | const char n = '1' <= c && c <= '9' ? c - '1' + 1 : 0; 44 | const int x = (i % 9) + 1; 45 | const int y = (i / 9) + 1; 46 | set(x, y, n); 47 | } 48 | } 49 | 50 | int get(int x, int y) const { return cells_[x-1][y-1]; } 51 | void set(int x, int y, int n) { cells_[x-1][y-1] = n; } 52 | 53 | int get(Point p) const { return get(p.x, p.y); } 54 | void set(Point p, int n) { set(p.x, p.y, n); } 55 | 56 | bool solved() const { 57 | for (int x = 1; x <= 9; ++x) { 58 | for (int y = 1; y <= 9; ++y) { 59 | if (get(x, y) == 0) { 60 | return false; 61 | } 62 | } 63 | } 64 | return true; 65 | } 66 | 67 | bool legal() const { 68 | for (int x = 1; x <= 9; ++x) { 69 | for (int y = 1; y <= 9; ++y) { 70 | for (int yy = 1; yy <= 9; ++yy) { 71 | if (y != yy && get(x, y) != 0 && get(x, yy) != 0 && get(x, y) == get(x, yy)) { 72 | return false; 73 | } 74 | } 75 | } 76 | } 77 | for (int x = 1; x <= 9; ++x) { 78 | for (int xx = 1; xx <= 9; ++xx) { 79 | for (int y = 1; y <= 9; ++y) { 80 | if (x != xx && get(x, y) != 0 && get(xx, y) != 0 && get(x, y) == get(xx, y)) { 81 | return false; 82 | } 83 | } 84 | } 85 | } 86 | for (int i = 1; i < 3; ++i) { 87 | for (int j = 1; j < 3; ++j) { 88 | for (int x = 3*i-2; x <= 3*i; ++x) { 89 | for (int xx = 3*i-2; xx <= 3*i; ++xx) { 90 | for (int y = 3*j-2; y <= 3*j; ++y) { 91 | for (int yy = 3*j-2; yy <= 3*j; ++yy) { 92 | if ((x != xx || y != yy) && get(x, y) != 0 && get(xx, yy) != 0 && get(x, y) == get(xx, yy)) { 93 | return false; 94 | } 95 | } 96 | } 97 | } 98 | } 99 | } 100 | } 101 | for (int x = 1; x <= 9; ++x) { 102 | for (int y = 1; y <= 9; ++y) { 103 | if (get(x, y) != 0 && (get(x, y) < 1 || get(x, y) > 9)) { 104 | return false; 105 | } 106 | } 107 | } 108 | return true; 109 | } 110 | 111 | void PrintDimacs(std::ostream* os) { 112 | *os << "c Sudoku instance" << std::endl; 113 | for (int x = 1; x <= 9; ++x) { 114 | for (int y = 1; y <= 9; ++y) { 115 | int i = x + (y - 1) * 9; 116 | int j = get(x, y); 117 | if (1 <= j && j <= 9) { 118 | *os << (i < 10 ? " " : "") << ' ' << i << '=' << j << ' ' << '0' << std::endl; 119 | } 120 | } 121 | } 122 | } 123 | 124 | private: 125 | int cells_[9][9]; 126 | }; 127 | 128 | #endif // EXAMPLES_SUDOKU_GAME_H_ 129 | 130 | -------------------------------------------------------------------------------- /examples/sudoku/printer.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2017 Christoph Schwering 3 | 4 | #ifndef EXAMPLES_SUDOKU_PRINTER_H_ 5 | #define EXAMPLES_SUDOKU_PRINTER_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include "game.h" 15 | #include "kb.h" 16 | 17 | typedef std::string Color; 18 | 19 | class Colors { 20 | public: 21 | virtual ~Colors() {} 22 | virtual std::string fill(int) const = 0; 23 | virtual Color reset() const = 0; 24 | virtual Color dim() const = 0; 25 | virtual Color black() const = 0; 26 | virtual Color red() const = 0; 27 | virtual Color green() const = 0; 28 | }; 29 | 30 | class TerminalColors : public Colors { 31 | public: 32 | std::string fill(int n) const override { return std::string(n, ' '); } 33 | Color reset() const override { return s(0); } 34 | Color dim() const override { return s(2); } 35 | Color black() const override { return s(30); } 36 | Color red() const override { return s(31); } 37 | Color green() const override { return s(32); } 38 | 39 | private: 40 | static Color s(int c) { 41 | std::stringstream ss; 42 | ss << "\033[" << c << "m"; 43 | return ss.str(); 44 | } 45 | }; 46 | 47 | class HtmlColors : public Colors { 48 | public: 49 | std::string fill(int n) const override { return std::string(n, '_'); } 50 | Color reset() const override { return s("reset"); } 51 | Color dim() const override { return s("dim"); } 52 | Color black() const override { return s("black"); } 53 | Color red() const override { return s("red"); } 54 | Color green() const override { return s("green"); } 55 | 56 | private: 57 | static Color s(const std::string& cls) { 58 | std::stringstream ss; 59 | ss << ""; 60 | return ss.str(); 61 | } 62 | }; 63 | 64 | class Printer { 65 | public: 66 | typedef std::string Label; 67 | 68 | Printer(const Colors* colors, std::ostream* os) : colors_(colors), os_(os) {} 69 | virtual ~Printer() = default; 70 | 71 | void Print(const Game& g) { 72 | const std::string DASH = "\u2550"; 73 | const std::string PIPE = "\u2551"; 74 | const std::string CROSS = "\u256c"; 75 | *os_ << colors_->fill(3); 76 | for (int x = 1; x <= 9; ++x) { 77 | *os_ << colors_->dim() << colors_->dim() << colors_->fill(1) << x << colors_->fill(1) << colors_->reset(); 78 | if (x == 3 || x == 6) { 79 | *os_ << colors_->dim() << colors_->fill(1) << colors_->reset(); 80 | } 81 | } 82 | *os_ << std::endl; 83 | for (int y = 1; y <= 9; ++y) { 84 | *os_ << colors_->dim() << colors_->fill(1) << y << colors_->fill(1) << colors_->reset(); 85 | for (int x = 1; x <= 9; ++x) { 86 | Label l = label(g, Point(x, y)); 87 | *os_ << colors_->fill(1) << l << colors_->fill(1); 88 | if (x == 3 || x == 6) { 89 | *os_ << colors_->dim() << PIPE << colors_->reset(); 90 | } 91 | } 92 | *os_ << std::endl; 93 | if (y == 3 || y == 6) { 94 | *os_ << colors_->fill(1) << colors_->dim() << colors_->fill(2); 95 | for (int x = 1; x <= 9; ++x) { 96 | *os_ << DASH << DASH << DASH; 97 | if (x == 3 || x == 6) { 98 | *os_ << CROSS; 99 | } 100 | } 101 | *os_ << colors_->reset() << std::endl; 102 | } 103 | } 104 | } 105 | 106 | virtual Label label(const Game&, Point) = 0; 107 | 108 | protected: 109 | const Colors* colors_; 110 | std::ostream* os_; 111 | }; 112 | 113 | class SimplePrinter : public Printer { 114 | public: 115 | using Printer::Printer; 116 | 117 | Label label(const Game& g, const Point p) override { 118 | if (g.get(p) > 0) { 119 | std::stringstream ss; 120 | ss << g.get(p); 121 | return Label(ss.str()); 122 | } else { 123 | return Label(" "); 124 | } 125 | } 126 | }; 127 | 128 | #endif // EXAMPLES_SUDOKU_PRINTER_H_ 129 | 130 | -------------------------------------------------------------------------------- /examples/sudoku/sudoku-js.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2017 Christoph Schwering 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "agent.h" 11 | #include "game.h" 12 | #include "kb.h" 13 | #include "printer.h" 14 | #include "timer.h" 15 | 16 | namespace logging { 17 | 18 | template> 19 | class StreamRedirector : public std::basic_streambuf { 20 | public: 21 | StreamRedirector(std::ostream* stream, TernaryPredicate writer = TernaryPredicate()) 22 | : stream_(stream), writer_(writer) { 23 | old_buf_ = stream_->rdbuf(this); 24 | } 25 | 26 | ~StreamRedirector() { stream_->rdbuf(old_buf_); } 27 | 28 | std::streamsize xsputn(const CharT* ptr, std::streamsize count) { 29 | writer_(ptr, count); 30 | return count; 31 | } 32 | 33 | typename Traits::int_type overflow(typename Traits::int_type i) { 34 | CharT c = Traits::to_char_type(i); 35 | writer_(&c, 1); 36 | return Traits::not_eof(i); 37 | } 38 | 39 | private: 40 | std::basic_ostream* stream_; 41 | std::streambuf* old_buf_; 42 | TernaryPredicate writer_; 43 | }; 44 | 45 | struct JsLogger { 46 | void operator()(const char* buf, std::streamsize n) { 47 | bool lf = false; 48 | for (std::streamsize i = 0; i < n; ++i) { 49 | if (buf[i] == '\r' || buf[i] == '\n') { 50 | lf = true; 51 | } 52 | } 53 | buf_ += std::string(buf, n); 54 | if (lf) { 55 | flush(); 56 | } 57 | } 58 | 59 | void flush() { 60 | EM_ASM_({ 61 | printLine(Pointer_stringify($0)); 62 | }, buf_.c_str()); 63 | buf_ = std::string(); 64 | } 65 | 66 | private: 67 | std::string buf_; 68 | }; 69 | 70 | static StreamRedirector* redirector_ = nullptr; 71 | 72 | } // namespace logging 73 | 74 | 75 | namespace game { 76 | 77 | static HtmlColors colors; 78 | 79 | static Game* game = nullptr; 80 | static KnowledgeBase* kb = nullptr; 81 | static KnowledgeBaseAgent* agent = nullptr; 82 | static Timer* timer_overall = nullptr; 83 | static SimplePrinter* printer = nullptr; 84 | static std::vector* split_counts = nullptr; 85 | 86 | void Finalize() { 87 | limbo::Symbol::Factory::Reset(); 88 | limbo::Term::Factory::Reset(); 89 | if (agent) 90 | delete agent; 91 | if (kb) 92 | delete kb; 93 | if (game) 94 | delete game; 95 | if (timer_overall) 96 | delete timer_overall; 97 | if (printer) 98 | delete printer; 99 | if (split_counts) 100 | delete split_counts; 101 | } 102 | 103 | void Init(const std::string& cfg, int max_k) { 104 | Finalize(); 105 | game = new Game(cfg); 106 | kb = new KnowledgeBase(game, max_k); 107 | timer_overall = new Timer(); 108 | agent = new KnowledgeBaseAgent(game, kb); 109 | printer = new SimplePrinter(&colors, &std::cout); 110 | split_counts = new std::vector(); 111 | split_counts->resize(max_k + 1); 112 | std::cout << "Initial configuration:" << std::endl; 113 | std::cout << std::endl; 114 | printer->Print(*game); 115 | std::cout << std::endl; 116 | std::cout << "Ready to play" << std::endl; 117 | } 118 | 119 | bool PlayTurn() { 120 | Timer timer_turn; 121 | timer_turn.start(); 122 | timer_overall->start(); 123 | const limbo::internal::Maybe r = agent->Explore(); 124 | timer_overall->stop(); 125 | timer_turn.stop(); 126 | if (r) { 127 | ++(*split_counts)[r.val.k]; 128 | std::cout << r.val.p << " = " << r.val.n << " found at split level " << r.val.k << std::endl; 129 | } 130 | std::cout << std::endl; 131 | printer->Print(*game); 132 | std::cout << std::endl; 133 | std::cout << "Last move took " << std::fixed << timer_turn.duration() << std::endl; 134 | kb->ResetTimer(); 135 | const bool game_over = game->solved() || !r; 136 | 137 | if (game_over) { 138 | std::cout << "Final board:" << std::endl; 139 | std::cout << std::endl; 140 | printer->Print(*game); 141 | std::cout << std::endl; 142 | if (game->solved() && game->legal()) { 143 | std::cout << colors.green() << "Solution is legal"; 144 | } else { 145 | std::cout << colors.red() << "Solution is illegal"; 146 | } 147 | std::cout << " [max-k: " << kb->max_k() << "; "; 148 | for (size_t k = 0; k < split_counts->size(); ++k) { 149 | const int n = (*split_counts)[k]; 150 | if (n > 0) { 151 | std::cout << "level " << k << ": " << n << "; "; 152 | } 153 | } 154 | std::cout << "runtime: " << timer_overall->duration() << " seconds]" << colors.reset() << std::endl; 155 | } 156 | 157 | return game_over; 158 | } 159 | 160 | } // namespace game 161 | 162 | extern "C" void limbo_init(const char* cfg, int max_k) { 163 | if (!logging::redirector_) { 164 | logging::redirector_ = new logging::StreamRedirector(&std::cout); 165 | } 166 | game::Init(cfg, max_k); 167 | } 168 | 169 | extern "C" int limbo_play_turn() { 170 | return game::PlayTurn() ? 1 : 0; 171 | } 172 | 173 | -------------------------------------------------------------------------------- /examples/sudoku/sudoku.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2017 Christoph Schwering 3 | // 4 | // Command line application that plays Sudoku. 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include "agent.h" 15 | #include "game.h" 16 | #include "kb.h" 17 | #include "printer.h" 18 | #include "timer.h" 19 | 20 | inline bool Play(const std::string& cfg, int max_k, const Colors& colors, std::ostream* os, bool print_dimacs = false) { 21 | Timer timer_overall; 22 | Game g(cfg); 23 | KnowledgeBase kb(max_k); 24 | if (print_dimacs) { kb.PrintDimacs(&std::cerr); g.PrintDimacs(&std::cerr); } 25 | kb.InitGame(&g); 26 | KnowledgeBaseAgent agent(&g, &kb); 27 | SimplePrinter printer(&colors, os); 28 | std::vector split_counts; 29 | split_counts.resize(max_k + 1); 30 | limbo::internal::Maybe r; 31 | *os << "Initial Sudoku:" << std::endl; 32 | *os << std::endl; 33 | printer.Print(g); 34 | do { 35 | Timer timer_turn; 36 | timer_turn.start(); 37 | timer_overall.start(); 38 | r = agent.Explore(); 39 | timer_overall.stop(); 40 | timer_turn.stop(); 41 | if (r) { 42 | ++split_counts[r.val.k]; 43 | *os << r.val.p << " = " << r.val.n << " found at split level " << r.val.k << std::endl; 44 | } 45 | *os << std::endl; 46 | printer.Print(g); 47 | *os << std::endl; 48 | *os << "Last move took " << std::fixed << timer_turn.duration() << std::endl; 49 | kb.ResetTimer(); 50 | } while (!g.solved() && g.legal() && r); 51 | const bool solved = g.solved() && g.legal(); 52 | std::cout << (solved ? colors.green() : colors.red()) << "Solution is " << (solved ? "" : "il") << "legal"; 53 | std::cout << " [max-k: " << kb.max_k() << "; "; 54 | for (size_t k = 0; k < split_counts.size(); ++k) { 55 | const int n = split_counts[k]; 56 | if (n > 0) { 57 | std::cout << "level " << k << ": " << n << "; "; 58 | } 59 | } 60 | std::cout << "runtime: " << timer_overall.duration() << " seconds]" << colors.reset() << std::endl; 61 | return solved; 62 | } 63 | 64 | int main(int argc, char *argv[]) { 65 | if (argc < 3) { 66 | std::cout << "Usage: " << argv[0] << " " << std::endl; 67 | return 2; 68 | } 69 | if (std::strlen(argv[1]) != 9*9) { 70 | std::cerr << "Config '" << argv[1] << "' is not 9*9 but " << std::strlen(argv[1]) << " characters long" << std::endl; 71 | return 3; 72 | } 73 | const char* cfg = argv[1]; 74 | int max_k = atoi(argv[2]); 75 | bool solved = Play(cfg, max_k, TerminalColors(), &std::cout, false); 76 | return solved ? 0 : 1; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /examples/sudoku/sudokus.txt: -------------------------------------------------------------------------------- 1 | 5.1.8...4.42.6.718..742..5..159...6.32..1.47..7.3.41.......834729..47...7....5..9 NYTimes grade easy (Jan 27) 2 | ...7.2....86...542291.8.6...1.2748..46..5.......81..93..7543..61.9....746.4..725. NYTimes grade easy (Jan 27) 3 | 2.8.47..11....3.98.5..8...7...67.14.6.34...2.91.3.8..6.86.52....328.67....1.3.6.2 NYTimes grade easy (Jan 30) 4 | .4...52.7.95127...721....9....35.1.4.17.6.83.4.2.1...51..643......5.14.337.....51 NYTimes grade easy (Jan 31) 5 | ..6...134..94.8...5.3..79..2..39.41.3..2..59.98...1.23.98.6...1.3.12..46.1...53.9 NYTimes grade easy (Feb 1) 6 | .4..72.1...7.1.64.192..4.8..1.5874...5.1...97..6..98.18.1.4..293.42.1....2.3....4 NYTimes grade easy (Feb 2) 7 | 5..167.4..4....851231..4...69851.3..4..98.1..1...4.6.9.25..1..7.643....2...4..96. NYTimes grade easy (Feb 3) 8 | .....831595.6.4....175..4.93...91..414...2.7.2..34..9.4.2...5.753.28......643.82. NYTimes grade easy (Feb 18) 9 | 10 | .75.1...............243..8.6..........4.71..535...46.7.....9.64....2.8....85..... NYTimes grade medium (Jan 27) 11 | .48.6.3..7.3....29........7.........425931.....1..........75.31...2...8.8..6...5. NYTimes grade medium (Jan 29) 12 | ...76..9....8......2...1.87.46.5...2.5....91...3..9....1...2.....2....36.....4... NYTimes grade medium (Jan 30) 13 | ...2....1..6.173..4.9...5.....4..2.8....5...45.....7..6.3........1.8..3....9.2... NYTimes grade medium (Jan 31) 14 | .2.....7....58....4..71.....8.6..79..39..528........3.1..2..9........1.365....... NYTimes grade medium (Feb 1) 15 | ...3...6..12..6...7.3...4.59.4..32...2...83.4..1.52...............9....7....71526 NYTimes grade medium (Feb 2) 16 | .7....21..21.....3.3.....8......3.....82..6......8..25..36.2.7......18.49...54... NYTimes grade medium (Feb 3) 17 | 8........2..63.......1..29.6....8.31.....7..2..2...9681..8....9.7...9.........34. NYTimes grade medium (Feb 18) 18 | 19 | 4..3..57......6.249....5...7..84...3.....2.9...86....2167............3.62........ NYTimes grade hard (Jan 27) 20 | .6.8...5.8.7.9.......3.7..8.5...924.6....1.......7.5.353.............1..9......82 NYTimes grade hard (Jan 29) 21 | .3.......8..9.4...9....57.26.7..3..9......1....51...3....4...2.4.98.2..7..3....6. NYTimes grade hard (Jan 30) 22 | ....9.8.6.4...5.12...6......32.....86.8..3..........57.2.7.......1962...3...5...9 NYTimes grade hard (Jan 31) 23 | .8.4.9...2....568......8.........1.76.2.......9.8..35.7..........1...5..5.692...4 NYTimes grade hard (Feb 1) 24 | ....7.....6.93.8....18............2.856.....7...5.83.......2.5...2..4...9.3....1. NYTimes grade hard (Feb 2) 25 | .....35...7.....81...1.89..4..92.3..7....4...1.....69.6..4.9......6....3.3....2.. NYTimes grade hard (Feb 3) 26 | .6..1...9.1....7....3..54.....9.71..5...23..81.......3.2...4..6...58........7.9.. NYTimes grade hard (Feb 18) 27 | 28 | 6..95.312..1.2.68....86.75..9678.24.5..146....1729..65.3.4....62.951..37174.32..8 WashPost grade 1 (1/16/17) 29 | 34785.1.6.861739.4.9564....8.9.276...........76.....32.28..43.1.1..38269...2615.. WashPost grade 1 (1/23/17) 30 | 7.48.352...829..343.1...8..4..576...653129...179.38..2..5.1.24....35..96.1..8..7. WashPost grade 1 (1/30/17) 31 | 32 | ..48......8.5.29.6.7...4.8.239..75617.8.51..4.45...837.9..4831....1.3.7..13..5.29 WashPost grade 2 (1/17/17) 33 | .9..6.85..8..712.3.31..5.....2..45..51..37......85..3.9....84...2...6....43.1962. WashPost grade 2 (1/19/17) 34 | 67.39..42149672.53...1.4.9.8.....41.291..65...5.8..6293.74.89.191.2.7....8..3.27. WashPost grade 2 (1/24/17) 35 | .8.759....1.....9...261478...14....62..5..3.87.5..1942.68.7.1341..3458674.3.86.59 WashPost grade 2 (1/31/17) 36 | 37 | 92.458....85.319.4...9..5..49....3....6.1.8.9...549.2..198.46.58...2549.5....3.1. WashPost grade 3 (1/18/17) 38 | 9.7.38..5.....59...5.7...615..187..287.2...59.......786985.....1.5.26...7.29.1586 WashPost grade 3 (1/25/17) 39 | 6.97...4..7.1.4.6....65...9......43..6.42...5..5836.....12.8...9.7..1....2.9.57.8 WashPost grade 3 (1/26/17) 40 | 41 | .96.51..3....93.1.3.12......684.9531.1.3.82979....5.4..53..6..41..5.......4...... WashPost grade 4 (1/20/17) 42 | 48..6..3.......9.62.69.3.7......736...8..6..7.61.....8...2987..19.6.....852....49 WashPost grade 4 (1/21/17) 43 | 18........5.28691..6...4...9.6..2.4..4..175.2....4968.4...6..........751.....14.9 WashPost grade 4 (1/14/17) 44 | 2...86..3...2.....8..79.....9.....15.8...5.2..61..2..8...654..2.45.27.89..7...5.4 WashPost grade 4 (1/27/17) 45 | 516.7.....948...172...5.9.41....84.3.23...8.6...7.......2.9...5.65..4........76.9 WashPost grade 4 (1/28/17) 46 | 47 | 7..65.4..8........154.7.2...7..4.83.....369..4..981.........62..275..1.4.4..12..7 WashPost grade 5 (1/15/17) 48 | ..1..73.67...93..5...86..7..49.....2..592....32.....5..5...9.2......87..9.4.1..6. WashPost grade 5 (1/22/17) 49 | 6..8.1....57....28..8....1..61..8.3..2.4.68.1....1...7.....21..843....79.......65 WashPost grade 5 (1/29/17) 50 | 51 | .5.61.2..78.....9.....9...1243.6......92..........3.6.6.58..9......2.1....2..6..4 WashPost grade expert (generated) 52 | 86....72....6..1981........2.1.368......8.4...869...3...8.4..1.47..95.8..1..67..5 WashPost grade expert (generated) 53 | 65.2.......7..52.63......7.73....98..96.2...1..8.9....1..95...4...4.25...7...3..9 WashPost grade expert (generated) 54 | 55 | -------------------------------------------------------------------------------- /examples/sudoku/test-and-eval-sudokus.sh: -------------------------------------------------------------------------------- 1 | F=$1 2 | 3 | for sudoku in $(cat $F) 4 | do 5 | echo -n "Preset cells: " 6 | echo -n $sudoku | sed 's/\.//g' | wc -c 7 | ./sudoku $sudoku 2 | grep Solution 8 | done 9 | 10 | -------------------------------------------------------------------------------- /examples/sudoku/test.sh: -------------------------------------------------------------------------------- 1 | mask=$1 2 | maxk=$2 3 | 4 | if [ "$maxk" == "" ] 5 | then 6 | maxk=2 7 | fi 8 | 9 | cat sudokus.txt | grep "$mask" | while read -r sudoku 10 | do 11 | sudoku=$(echo $sudoku | sed -e 's/ .\+$//g') 12 | if [ "$sudoku" != "" ] 13 | then 14 | ./sudoku $sudoku $maxk | grep Solution || exit 15 | fi 16 | done 17 | 18 | -------------------------------------------------------------------------------- /examples/sudoku/timer.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2014 Christoph Schwering 3 | 4 | #ifndef EXAMPLES_SUDOKU_TIMER_H_ 5 | #define EXAMPLES_SUDOKU_TIMER_H_ 6 | 7 | #include 8 | 9 | class Timer { 10 | public: 11 | Timer() : start_(std::clock()) {} 12 | 13 | void start() { 14 | start_ = std::clock() - (end_ != 0 ? end_ - start_ : 0); 15 | ++rounds_; 16 | } 17 | void stop() { end_ = std::clock(); } 18 | void reset() { start_ = 0; end_ = 0; rounds_ = 0; } 19 | 20 | double duration() const { return (end_ - start_) / (double) CLOCKS_PER_SEC; } 21 | int rounds() const { return rounds_; } 22 | double avg_duration() const { return duration() / rounds_; } 23 | 24 | private: 25 | std::clock_t start_; 26 | std::clock_t end_ = 0; 27 | int rounds_ = 0; 28 | }; 29 | 30 | #endif // EXAMPLES_SUDOKU_TIMER_H_ 31 | 32 | -------------------------------------------------------------------------------- /examples/tui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable (tui tui.cc linenoise/linenoise.c) 2 | target_link_libraries (tui LINK_PUBLIC limbo) 3 | 4 | 5 | file (GLOB tests RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "test-[^q]*.limbo" "example-*.limbo") 6 | foreach (test ${tests}) 7 | add_test (NAME ${test} COMMAND ./tui ${test}) 8 | endforeach () 9 | 10 | 11 | find_package (Emscripten) 12 | if (EMCC) 13 | if (CMAKE_BUILD_TYPE MATCHES Release) 14 | separate_arguments(FLAGS UNIX_COMMAND "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") 15 | add_custom_command (OUTPUT tui-js.js tui-js.js.mem 16 | COMMAND ${EMCC} ${FLAGS} -I../../src tui-js.cc -o tui-js.js 17 | -s EXPORTED_FUNCTIONS=['_limbo_init','_limbo_parse','_limbo_free'] 18 | -s TOTAL_MEMORY=16777216 19 | DEPENDS tui-js.cc "*.h" 20 | VERBATIM) 21 | add_custom_command (OUTPUT jquery.terminal-1.0.10.min.js COMMAND cp jquery.terminal/js/jquery.terminal-1.0.10.min.js .) 22 | add_custom_command (OUTPUT jquery.mousewheel-min.js COMMAND cp jquery.terminal/js/jquery.mousewheel-min.js .) 23 | add_custom_command (OUTPUT unix_formatting.js COMMAND cp jquery.terminal/js/unix_formatting.js .) 24 | add_custom_command (OUTPUT jquery.terminal-1.0.10.css COMMAND cp jquery.terminal/css/jquery.terminal-1.0.10.css .) 25 | add_custom_target (tui-js DEPENDS tui-js.js tui-js.js.mem jquery.terminal-1.0.10.min.js jquery.mousewheel-min.js unix_formatting.js jquery.terminal-1.0.10.css) 26 | add_dependencies (tui tui-js) 27 | endif () 28 | endif () 29 | 30 | -------------------------------------------------------------------------------- /examples/tui/README.md: -------------------------------------------------------------------------------- 1 | # Terminal 2 | 3 | This is a simple text interface to define and query knowledge bases. 4 | There are two ways to run this demo: 5 | 6 | * You can run it in your browser: 7 | . 8 | * You can compile and run it in the terminal; input is read from stdin then: 9 | run `cmake ../../ && make` and then 10 | run `./terminal example-father-of-sonny.txt`. 11 | 12 | -------------------------------------------------------------------------------- /examples/tui/battleship-pos.hs: -------------------------------------------------------------------------------- 1 | -- Simple Haskell program that generates KB clauses for the position functions. 2 | 3 | n (x,y) = (x,y-1) 4 | e (x,y) = (x+1,y) 5 | s (x,y) = (x,y+1) 6 | w (x,y) = (x-1,y) 7 | ne (x,y) = (x+1,y-1) 8 | se (x,y) = (x+1,y+1) 9 | nw (x,y) = (x-1,y-1) 10 | sw (x,y) = (x-1,y+1) 11 | 12 | xrange = [1..4] 13 | yrange = [1..4] 14 | 15 | valid (x,y) = x `elem` xrange && y `elem` yrange 16 | 17 | kb1 fname (x,y) (x',y') = "KB: "++ fname ++"(p" ++ show x ++ show y ++")=p" ++ show x' ++ show y' ++ " " 18 | 19 | kb f fn = unlines $ [ foldr (++) "" $ map (uncurry (kb1 fn)) $ filter (\(_,p) -> valid p) $ map (\p -> (p, f p)) $ [(x,y) | x <- xrange] | y <- yrange] 20 | 21 | main = putStrLn $ unlines $ map (uncurry kb) [(n,"n"),(e,"e"),(s,"s"),(w,"w"),(ne,"ne"),(se,"se"),(sw,"sw"),(nw,"nw")] 22 | 23 | -------------------------------------------------------------------------------- /examples/tui/example-battleship-1x4.limbo: -------------------------------------------------------------------------------- 1 | // A 1x4-battleship game with a 3-ship. 2 | // The output of the game is very limited; sorry for that. 3 | 4 | Call: disable_query_logging() 5 | 6 | Sort POS 7 | Var p, q -> POS 8 | Name p0, p1, p2, p3, p4, p5 -> POS 9 | Fun n/1, s/1 -> POS 10 | 11 | KB: n(p1)=p0 12 | KB: n(p2)=p1 13 | KB: n(p3)=p2 14 | KB: n(p4)=p3 15 | KB: n(p5)=p4 16 | 17 | // KB: ~n(p1)=p4 18 | // KB: ~s(p4)=p3 19 | 20 | KB: n(s(p))=p 21 | KB: s(n(p))=p 22 | // KB: ~n(p)=p 23 | // KB: ~s(p)=p 24 | 25 | // KB: s(p0)=p1 26 | // KB: s(p1)=p2 27 | // KB: s(p2)=p3 28 | // KB: s(p3)=p4 29 | // KB: s(p4)=p5 30 | 31 | Sort SHIP 32 | Var x, y -> SHIP 33 | Name three -> SHIP 34 | Fun head/1 -> POS 35 | Fun body/1 -> POS 36 | Fun tail/1 -> POS 37 | 38 | Sort BOOL 39 | Name T -> BOOL 40 | Fun water/1 -> BOOL 41 | Fun fired/1 -> BOOL 42 | 43 | KB: s(head(three))=body(three) 44 | KB: n(body(three))=head(three) 45 | KB: s(body(three))=tail(three) 46 | KB: n(tail(three))=body(three) 47 | 48 | KB: ~water(head(three))=T 49 | KB: ~water(body(three))=T 50 | KB: ~water(tail(three))=T 51 | 52 | KB: water(n(head(three)))=T 53 | KB: water(s(tail(three)))=T 54 | 55 | KB: p=p1 v p=p2 v p=p3 v p=p4 v water(p)=T 56 | // We don't need the following in the KB. If we do have it, however, 57 | // split level 1 suffices for the assertions below. 58 | //KB: head(three)=p v body(three)=p v tail(three)=p v water(p)=T 59 | Assert: G Fa p K<2> (head(three)=p v body(three)=p v tail(three)=p v water(p)=T) 60 | 61 | Call: bs_init(p1, p2, p3, p4) 62 | Call: bs_print() 63 | 64 | 65 | while Ex p G (~K<0> fired(p)=T ^ ~K<2> water(p)=T) { 66 | for P -> POS G (~K<0> fired(P)=T ^ K<2> ~water(P)=T) { 67 | Call: bs_fire(P) 68 | Call: print(P) 69 | } else if P -> POS G (~K<0> fired(P)=T ^ ~K<2> water(P)=T ^ ~K<2> ~water(P)=T) { 70 | Call: bs_fire(P) 71 | Call: print(P,P) 72 | } 73 | Call: bs_print() 74 | } 75 | 76 | -------------------------------------------------------------------------------- /examples/tui/example-birth.limbo: -------------------------------------------------------------------------------- 1 | Rigid Sort Action 2 | Sort Human, Result 3 | Fun birth/2, test/2 -> Action 4 | Fun spouseOf/1, motherOf/1, fatherOf/1 -> Human 5 | Sensor Fun sf/Action -> Result 6 | Name Sally, Mia, Frank, Fred -> Human 7 | Name Yes, No -> Result 8 | Var a -> Action 9 | Var x, y, z -> Human 10 | Var r -> Result 11 | 12 | Real: spouseOf(Mia) = Frank 13 | 14 | KB: spouseOf(Mia) = Frank v spouseOf(Mia) = Fred 15 | 16 | KB: [] [a] motherOf(x) = y <-> a = birth(y,x) v a /= birth(y,x) ^ motherOf(x) = y 17 | KB: [] [a] fatherOf(x) = y <-> ex z (a = birth(z,x) ^ spouseOf(z) = y) v fa z (a /= birth(z,x) ^ fatherOf(x) = y) 18 | KB: [] sf(a) = r <-> ex x ex y (a = test(x,y) ^ fatherOf(x) = y) ^ r = Yes v fa x fa y (a /= test(x,y) v fatherOf(x) /= y) ^ r = No 19 | 20 | REG [birth(Mia,Sally)] K<0> (motherOf(Sally) = Mia) 21 | REG [birth(Mia,Sally)] M<1> (fatherOf(Sally) /= Frank) 22 | REG [birth(Mia,Sally)] K<1> (fatherOf(Sally) = Frank v fatherOf(Sally) = Fred) 23 | REG [birth(Mia,Sally)] [test(Sally,Fred)] K<1> fatherOf(Sally) = Frank 24 | 25 | -------------------------------------------------------------------------------- /examples/tui/example-rich-father.limbo: -------------------------------------------------------------------------------- 1 | // Are Frank or Fred rich? 2 | 3 | Sort BOOL, HUMAN 4 | Name T -> BOOL 5 | Name Frank, Fred, Sally -> HUMAN 6 | Fun rich/1 -> BOOL 7 | Fun fatherOf/1 -> HUMAN 8 | Var x -> HUMAN 9 | 10 | // All we know is that Sally's father is Frank or Fred and that he's rich. 11 | KB: fatherOf(Sally) = Frank v fatherOf(Sally) = Fred 12 | KB: rich(fatherOf(Sally)) = T 13 | 14 | // It's explicit knowledge that Frank/Fred is the father, then Frank is rich. 15 | K<0> (fatherOf(Sally) = Frank -> rich(Frank) = T) 16 | 17 | // At belief level 1, it is believed that that Frank or Fred are rich. 18 | K<0> (rich(Frank) = T v rich(Fred) = T) 19 | K<1> (rich(Frank) = T v rich(Fred) = T) 20 | 21 | // At belief level 1, it is considered possible that Frank is the father. 22 | M<0> (fatherOf(Sally) = Frank) 23 | M<1> (fatherOf(Sally) = Frank) 24 | 25 | // At belief level 1, it is considered possible that Frank is rich. 26 | M<0> (rich(Frank) = T) 27 | M<1> (rich(Frank) = T) 28 | 29 | // We know Sally's father is rich, but we don't know who it is. 30 | K<1> ex x (fatherOf(Sally) = x ^ rich(x) = T ^ M<1> fatherOf(Sally) /= x) 31 | 32 | -------------------------------------------------------------------------------- /examples/tui/example-siblings.limbo: -------------------------------------------------------------------------------- 1 | // Are Sally and Sonny siblings? 2 | 3 | Sort HUMAN 4 | Sort BOOL 5 | 6 | Variable x -> HUMAN 7 | Variable y -> HUMAN 8 | Variable z -> HUMAN 9 | 10 | Name Mary -> HUMAN 11 | Name Mia -> HUMAN 12 | Name Frank -> HUMAN 13 | Name Fred -> HUMAN 14 | Name Sally -> HUMAN 15 | Name Sonny -> HUMAN 16 | Name T -> BOOL 17 | 18 | Function fatherOf/1 -> HUMAN 19 | Function motherOf/1 -> HUMAN 20 | Function siblings/2 -> BOOL 21 | 22 | // Sally's parents are Frank and either Mary or Mia. 23 | KB: motherOf(Sally) == Mary || motherOf(Sally) == Mia 24 | KB: fatherOf(Sally) == Frank 25 | 26 | // Sonny's parents are Mary and either Frank or Fred. 27 | KB: motherOf(Sonny) == Mary 28 | KB: fatherOf(Sonny) == Frank || fatherOf(Sonny) == Fred 29 | 30 | // When x and y have they same mother or father, they are siblings. 31 | KB: x != y && motherOf(x) == motherOf(y) -> siblings(x, y) == T 32 | KB: x != y && fatherOf(x) == fatherOf(y) -> siblings(x, y) == T 33 | KB: siblings(x, y) == siblings(y, x) 34 | 35 | // Mother and father of any person are not siblings. 36 | KB: siblings(motherOf(z), fatherOf(z)) != T 37 | 38 | // Mia and Frank or Mary and Fred are siblings. 39 | KB: siblings(Mia, Frank) == T || siblings(Mary, Fred) == T 40 | 41 | // If Mia and Frank are siblings, they cannot have Sally together, so Sally's 42 | // mother must be Mary. Mary is also Sonny's mother, so they're siblings. 43 | // If Mary and Fred are siblings, they cannot have Sonny together, so Sonny's 44 | // father must be Frank. Frank is also Sally's father, so they're siblings. 45 | G Know<0> siblings(Sally, Sonny) == T 46 | G Know<1> siblings(Sally, Sonny) == T 47 | G Know<2> siblings(Sally, Sonny) == T 48 | 49 | -------------------------------------------------------------------------------- /examples/tui/example-unknown-father.limbo: -------------------------------------------------------------------------------- 1 | // Who's Sonny's father, Frank or Fred? 2 | 3 | Sort HUMAN 4 | Sort BOOL 5 | 6 | Variable x -> HUMAN 7 | Variable y -> HUMAN 8 | 9 | Name Mary -> HUMAN 10 | Name Frank -> HUMAN 11 | Name Fred -> HUMAN 12 | Name Sonny -> HUMAN 13 | Name True -> BOOL 14 | 15 | Function fatherOf/1 -> HUMAN 16 | Function motherOf/1 -> HUMAN 17 | 18 | KB: motherOf(Sonny) == Mary 19 | KB: fatherOf(Sonny) == Frank || fatherOf(Sonny) == Fred 20 | 21 | G Know<0> (fatherOf(Sonny) == Frank || fatherOf(Sonny) == Fred) 22 | 23 | Let phi := Ex x (x == fatherOf(Sonny)) 24 | G Know<0> phi 25 | G Know<1> phi 26 | 27 | Let phi := Frank == fatherOf(Sonny) 28 | G Cons<0> phi 29 | G Cons<1> phi 30 | 31 | G Know<0> (Fred == fatherOf(Sonny) && Frank == fatherOf(Sonny) || Fred == fatherOf(Sonny)) 32 | 33 | Let phi := motherOf(Sonny) == fatherOf(Sonny) 34 | G Know<0> phi 35 | G Cons<0> phi 36 | G Know<0> !phi 37 | G Cons<0> !phi 38 | G Cons<1> !phi 39 | 40 | -------------------------------------------------------------------------------- /examples/tui/example-veggie.limbo: -------------------------------------------------------------------------------- 1 | // If she's not Italian, is she a Vegatarian? 2 | 3 | Sort FOOD 4 | Sort BOOL 5 | 6 | Name T -> BOOL 7 | Name roo -> FOOD 8 | 9 | Var x -> FOOD 10 | 11 | Fun Aussie/0 -> BOOL 12 | Fun Italian/0 -> BOOL 13 | Fun Eats/1 -> BOOL 14 | Fun Meat/1 -> BOOL 15 | Fun Veggie/0 -> BOOL 16 | 17 | Let falsum := T /= T 18 | Let truth := ~falsum 19 | 20 | // The following conditionals are all the agent believes. In the formal logic, 21 | // there is just one pair of split levels for this only-believing. In this 22 | // implementation, there is one such pair of split levels per each conditional. 23 | // The only reason for this departure from the theory is that it was a little 24 | // less work to implement. 25 | 26 | // Most Aussies are not Italian, and vice-versa. 27 | KB: G Bel<1,1> Aussie = T ==> Italian != T 28 | KB: G Bel<1,1> Italian = T ==> Aussie != T 29 | 30 | // Most Aussies eat Kangaroo meat. 31 | KB: G Bel<1,1> Aussie = T ==> Eats(roo) = T 32 | 33 | // She's presumably Italian or a Vegetarian, and 34 | // if she's not Italian, she's probably Australian. 35 | KB: G Bel<1,1> truth ==> (Italian = T || Veggie = T) 36 | KB: G Bel<1,1> Italian != T ==> Aussie = T 37 | 38 | // Kangaroo is definitely meat, and Vegetarians don't eat meat. 39 | KB: G Bel<1,1> Meat(roo) != T ==> falsum 40 | KB: G Bel<1,1> ~Fa x ((Veggie == T && Meat(x) == T) -> Eats(x) != T) ==> falsum 41 | 42 | 43 | // The question is now: 44 | // If she's not Italian, is she a Vegetarian? 45 | // We find that out at belief levels 1, 1. 46 | Bel<0,0> Italian != T ==> Veggie != T 47 | G Bel<0,0> Italian != T ==> Veggie != T 48 | Bel<0,1> Italian != T ==> Veggie != T 49 | G Bel<0,1> Italian != T ==> Veggie != T 50 | Bel<1,0> Italian != T ==> Veggie != T 51 | G Bel<1,0> Italian != T ==> Veggie != T 52 | Bel<1,1> Italian != T ==> Veggie != T 53 | G Bel<1,1> Italian != T ==> Veggie != T 54 | 55 | -------------------------------------------------------------------------------- /examples/tui/sudoku-rep.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | for arg in sys.argv[1:]: 6 | print "// %s" % arg 7 | if len(arg) != 9*9: 8 | print "// CAUTION: game has only length %d" % len(arg) 9 | 10 | n = 0 11 | for c in arg: 12 | if n % 9 == 0: 13 | print "// ", 14 | if ord('1') <= ord(c) and ord(c) <= ord('9'): 15 | print (ord(c) - ord('0')), 16 | else: 17 | print " ", 18 | n = n + 1 19 | if n % 9 == 0: 20 | print 21 | 22 | print "if K<0> game=N {" 23 | n = 0 24 | for c in arg: 25 | if ord('1') <= ord(c) and ord(c) <= ord('9'): 26 | print " KB: val(n%d,n%d)=n%d" % ( 27 | (n % 9) + 1, 28 | (n / 9) + 1, 29 | ord(c) - ord('0')) 30 | n = n + 1 31 | print "}" 32 | 33 | -------------------------------------------------------------------------------- /examples/tui/sudoku.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2017 Christoph Schwering 3 | 4 | #ifndef EXAMPLES_TEXT_INTERFACE_SUDOKU_H_ 5 | #define EXAMPLES_TEXT_INTERFACE_SUDOKU_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "timer.h" 18 | 19 | struct SudokuCallbacks { 20 | template 21 | bool operator()(T* ctx, const std::string& proc, const std::vector& args) { 22 | if (proc == "su_init") { 23 | ns_ = args; 24 | } else if (proc == "su_print") { 25 | if (timer_.started()) { 26 | timer_.stop(); 27 | } 28 | std::cout << "Sudoku:" << std::endl; 29 | std::size_t n_known = 0; 30 | for (size_t y = 0; y < ns_.size(); ++y) { 31 | for (size_t x = 0; x < ns_.size(); ++x) { 32 | bool known = false; 33 | for (size_t n = 0; n < ns_.size(); ++n) { 34 | const limbo::Term Val = ctx->CreateTerm(ctx->LookupFunction("val"), {ns_[x], ns_[y]}); 35 | const limbo::Clause c{limbo::Literal::Eq(Val, ns_[n])}; 36 | bool b = ctx->kb().Entails(*limbo::Formula::Factory::Know(0, limbo::Formula::Factory::Atomic(c))); 37 | if (b) { 38 | using limbo::format::operator<<; 39 | std::stringstream ss; 40 | ss << ns_[n]; 41 | std::cout << ss.str().substr(1); 42 | known = true; 43 | ++n_known; 44 | } 45 | } 46 | if (!known) { 47 | std::cout << " "; 48 | } 49 | std::cout << " "; 50 | } 51 | std::cout << std::endl; 52 | } 53 | std::cout << n_known << " cells known"; 54 | if (timer_.started()) { 55 | std::cout << " (" 56 | << timer_.duration() << "s elapsed, " 57 | << timer_.avg_duration() << "s on average over " 58 | << timer_.rounds() << " moves)"; 59 | } 60 | std::cout << std::endl; 61 | timer_.start(); 62 | } else { 63 | return false; 64 | } 65 | return true; 66 | } 67 | 68 | private: 69 | std::vector ns_; 70 | Timer timer_; 71 | }; 72 | 73 | #endif // EXAMPLES_TEXT_INTERFACE_SUDOKU_H_ 74 | 75 | -------------------------------------------------------------------------------- /examples/tui/test-bat.limbo: -------------------------------------------------------------------------------- 1 | Sort BOOL 2 | Name T -> BOOL 3 | 4 | Sort ENTITY 5 | Name Nothing -> ENTITY 6 | Name Box -> ENTITY 7 | Fun holding/0 -> ENTITY 8 | Var x -> ENTITY 9 | Var y -> ENTITY 10 | 11 | 12 | Rigid Sort ACTION 13 | Fun pickup/1 -> ACTION 14 | Name drop -> ACTION 15 | Name look -> ACTION 16 | Var a -> ACTION 17 | 18 | Sensor Fun seen/ACTION -> ENTITY 19 | 20 | Real: holding = Box 21 | 22 | // KB: [] poss(a) = T <-> ex x (a = pickup(x) ^ holding = Nothing) v (a = drop ^ holding /= Nothing) 23 | // KB: [] poss(pickup(x)) = T -> holding = Nothing 24 | // KB: [] poss(drop) = T -> holding /= Nothing 25 | // KB: [] poss(pickup(x)) = T <- holding = Nothing 26 | // KB: [] poss(drop) = T <- holding /= Nothing 27 | 28 | KB: [] seen(look) = x <-> holding = x 29 | 30 | KB: [] [a] holding = x <-> a = pickup(x) v (a = drop ^ x = Nothing) v fa y (a /= pickup(y) ^ a /= drop ^ holding = x) 31 | 32 | Assert: holding = Box 33 | //Assert: K<0> holding = Nothing 34 | Assert: K<0> REG [pickup(Box)] holding = Box 35 | Refute: K<0> REG [pickup(Box)] holding = Nothing 36 | Assert: REG [pickup(Box)] K<0> holding = Box 37 | Refute: REG [pickup(Box)] K<0> holding = Nothing 38 | Assert: REG [look] K<1> holding = Box 39 | 40 | -------------------------------------------------------------------------------- /examples/tui/test-battleship-1x4.limbo: -------------------------------------------------------------------------------- 1 | // A 1x4-battleship game with a 3-ship. 2 | 3 | Sort POS 4 | Var p, q -> POS 5 | Name p0, p1, p2, p3, p4, p5 -> POS 6 | Fun n/1, s/1 -> POS 7 | 8 | KB: n(p1)=p0 9 | KB: n(p2)=p1 10 | KB: n(p3)=p2 11 | KB: n(p4)=p3 12 | KB: n(p5)=p4 13 | 14 | // KB: ~n(p1)=p4 15 | // KB: ~s(p4)=p3 16 | 17 | KB: n(s(p))=p 18 | KB: s(n(p))=p 19 | // KB: ~n(p)=p 20 | // KB: ~s(p)=p 21 | 22 | // KB: s(p0)=p1 23 | // KB: s(p1)=p2 24 | // KB: s(p2)=p3 25 | // KB: s(p3)=p4 26 | // KB: s(p4)=p5 27 | 28 | Sort SHIP 29 | Var x, y -> SHIP 30 | Name three -> SHIP 31 | Fun head/1 -> POS 32 | Fun body/1 -> POS 33 | Fun tail/1 -> POS 34 | 35 | Sort BOOL 36 | Name T -> BOOL 37 | Fun water/1 -> BOOL 38 | Fun fired/1 -> BOOL 39 | 40 | KB: s(head(three))=body(three) 41 | KB: n(body(three))=head(three) 42 | KB: s(body(three))=tail(three) 43 | KB: n(tail(three))=body(three) 44 | 45 | KB: ~water(head(three))=T 46 | KB: ~water(body(three))=T 47 | KB: ~water(tail(three))=T 48 | 49 | KB: water(n(head(three)))=T 50 | KB: water(s(tail(three)))=T 51 | 52 | KB: p=p1 v p=p2 v p=p3 v p=p4 v water(p)=T 53 | // We don't need the following in the KB. If we do have it, however, 54 | // split level 1 suffices for the assertions below. 55 | // KB: head(three)=p v body(three)=p v tail(three)=p v water(p)=T 56 | Assert: Fa p K<2> (head(three)=p v body(three)=p v tail(three)=p v water(p)=T) 57 | 58 | Call: bs_init(p1, p2, p3, p4) 59 | Call: bs_print() 60 | 61 | Call: bs_fire(p1) 62 | Call: bs_fire(p3) 63 | Call: bs_print() 64 | Assert: K<1> ~water(p1)=T 65 | Assert: K<1> ~water(p3)=T 66 | Assert: K<2> head(three)=p1 67 | Assert: K<2> body(three)=p2 68 | Assert: K<2> tail(three)=p3 69 | Refute: K<2> (body(three)=p2 ^ body(three)/=p2) 70 | Assert: K<1> water(p0)=T 71 | Assert: K<1> ~water(p1)=T 72 | Assert: K<2> ~water(p2)=T 73 | Assert: K<1> ~water(p3)=T 74 | Assert: K<2> water(p4)=T 75 | Assert: K<1> water(p5)=T 76 | 77 | -------------------------------------------------------------------------------- /examples/tui/test-control.limbo: -------------------------------------------------------------------------------- 1 | // Tests the control structures: if, while, for. 2 | 3 | Sort OBJ, BOOL 4 | Var x -> OBJ 5 | Name n -> OBJ 6 | Name m -> OBJ 7 | Name T -> BOOL 8 | Fun p/1 -> BOOL 9 | 10 | Let true := T = T 11 | Let false := ~true 12 | 13 | If true 14 | Begin 15 | Assert: true 16 | End 17 | 18 | If false 19 | Begin 20 | Refute: true 21 | End 22 | 23 | If true 24 | Begin 25 | Assert: true 26 | End 27 | Else 28 | Begin 29 | Refute: true 30 | End 31 | 32 | if false { 33 | Refute: true 34 | } else { 35 | Assert: true 36 | } 37 | 38 | if false { 39 | Refute: true 40 | } else if false { 41 | Assert: false 42 | } else { 43 | Assert: n = n 44 | } 45 | 46 | for X in n, m -> OBJ 47 | true { 48 | Assert: X = X 49 | } else { 50 | Assert: false 51 | } 52 | 53 | for Y in n -> OBJ 54 | true { 55 | Assert: Y = Y 56 | } else { 57 | Assert: false 58 | } 59 | 60 | KB: p(n)=T 61 | 62 | for Z -> OBJ 63 | K<0> p(Z)=T { 64 | Assert: Z /= n v Z /= m 65 | } else { 66 | Assert: false 67 | } 68 | 69 | for Z -> OBJ 70 | K<0> p(Z)=T { 71 | Assert: Z /= n v Z /= m 72 | } else { 73 | Assert: false 74 | } 75 | 76 | for Z -> OBJ 77 | K<0> ~p(Z)=T { 78 | Assert: false 79 | } else { 80 | Assert: true 81 | } 82 | 83 | -------------------------------------------------------------------------------- /examples/tui/test-functions.limbo: -------------------------------------------------------------------------------- 1 | // Simple sanity check for functions. 2 | 3 | Sort OBJECT 4 | 5 | Fun a/0 -> OBJECT 6 | Fun b/0 -> OBJECT 7 | Fun f/1 -> OBJECT 8 | Fun g/1 -> OBJECT 9 | Fun h/2 -> OBJECT 10 | Name m, n, o -> OBJECT 11 | Var x, y, z -> OBJECT 12 | 13 | Refute: Know<3> a == b 14 | Refute: Know<3> f(a) == g(a) 15 | Refute: Know<3> f(a) == g(b) 16 | Refute: Know<3> f(a) == g(a) 17 | Refute: Know<3> f(a) == g(b) 18 | 19 | Assert: Know<0> (a == n v a != n) // because of Clause::valid() 20 | Assert: Know<1> (a == n v a != n) 21 | 22 | Refute: Know<0> Ex x a == x 23 | Assert: Know<1> Ex x a == x 24 | 25 | Refute: Ex x Know<1> f(x) == x 26 | Refute: Fa x Know<1> f(x) == x 27 | Refute: Know<1> Fa x f(x) == x 28 | Refute: Know<1> Ex x f(x) != x 29 | 30 | Refute: Know<1> (Fa x Fa y h(x,y) == x || Ex x Ex y h(x,y) != y) 31 | Refute: Know<1> (Fa x Fa y f(x) == y || Ex y f(y) != y) 32 | Refute: Know<1> (Fa x Fa y f(x) == y || Ex z f(z) != z) 33 | 34 | -------------------------------------------------------------------------------- /examples/tui/test-guarantee.limbo: -------------------------------------------------------------------------------- 1 | Sort BOOL 2 | Fun a/0, b/0 -> BOOL 3 | Fun p/0, q/0 -> BOOL 4 | Name T -> BOOL 5 | 6 | Let true := T=T 7 | Let false := ~true 8 | 9 | KB: a=T v b=T 10 | KB: a=T v ~b=T 11 | KB: ~a=T v b=T 12 | KB: ~a=T v ~b=T 13 | 14 | KB: p=T v q=T 15 | 16 | Assert: K<0> true 17 | 18 | Refute: K<0> false 19 | Assert: K<1> false 20 | Assert: K<1> G false 21 | 22 | Refute: G K<1> false 23 | Refute: G K<2> false 24 | Assert: ~ G K<2> false 25 | 26 | Assert: K<0> (p=T v q=T) 27 | Refute: K<0> ((p=T v q=T) ^ M<2> p=T) 28 | Assert: K<0> ((p=T v q=T) ^ G M<2> p=T) 29 | Assert: G K<0> ((p=T v q=T) ^ M<2> p=T) 30 | Assert: G K<0> ((p=T v q=T) ^ G M<2> p=T) 31 | Refute: ~ G K<0> ((p=T v q=T) ^ G M<2> p=T) 32 | 33 | -------------------------------------------------------------------------------- /examples/tui/test-introspection-constant.limbo: -------------------------------------------------------------------------------- 1 | // Tests introspection with KB: p(c). 2 | 3 | Sort OBJ 4 | Var x -> OBJ 5 | Name m, n -> OBJ 6 | Fun c/0 -> OBJ 7 | 8 | KB: c = m v c = n 9 | 10 | Refute: K<0> Ex x c = x 11 | Refute: M<0> Ex x c = x 12 | Assert: K<1> Ex x c = x 13 | Assert: M<1> Ex x c = x 14 | 15 | Refute: Ex x K<0> c = x 16 | Refute: Ex x M<0> c = x 17 | Refute: Ex x K<1> c = x 18 | Assert: Ex x M<1> c = x 19 | 20 | Assert: Fa x ~ K<1> c = x 21 | Refute: Fa x M<1> c = x 22 | Refute: Fa x ~ K<1> c /= x 23 | Assert: Ex x K<1> c /= x 24 | Assert: Fa x M<2> c /= x 25 | 26 | Assert: K<1> Ex x (c = x ^ M<1> c /= x) 27 | Assert: K<1> Fa x (c = x -> M<1> c /= x) 28 | Assert: K<1> Ex x (c = x ^ ~K<1>~ c = x) 29 | 30 | -------------------------------------------------------------------------------- /examples/tui/test-introspection-disjunction.limbo: -------------------------------------------------------------------------------- 1 | // Tests introspection with KB: p(m) v p(n). 2 | 3 | Sort OBJ 4 | Var x -> OBJ 5 | Name n -> OBJ 6 | 7 | Assert: n = n 8 | Assert: Ex x x = x 9 | Assert: Fa x x = x 10 | Assert: Ex x K<0> x = x 11 | Assert: Ex x K<0> x = n 12 | Assert: Fa x K<0> x = x 13 | Refute: Fa x K<0> x = n 14 | 15 | 16 | Sort BOOL 17 | Fun p/1 -> BOOL 18 | Name m -> OBJ 19 | Name T -> BOOL 20 | 21 | KB: p(m) = T v p(n) = T 22 | 23 | Refute: K<0> Ex x p(x) = T 24 | Refute: M<0> Ex x p(x) = T 25 | Assert: K<1> Ex x p(x) = T 26 | Assert: M<1> Ex x p(x) = T 27 | 28 | Refute: Ex x K<0> p(x) = T 29 | Refute: Ex x M<0> p(x) = T 30 | Refute: Ex x K<1> p(x) = T 31 | Assert: Ex x M<1> p(x) = T 32 | 33 | Assert: Fa x ~ K<1> p(x) = T 34 | Assert: Fa x M<1> p(x) = T 35 | Assert: Fa x ~ K<1> p(x) /= T 36 | Assert: Fa x M<1> p(x) /= T 37 | 38 | Assert: K<1> Ex x (p(x) = T ^ M<1> p(x) /= T) 39 | Assert: K<1> Fa x (p(x) = T -> M<1> p(x) /= T) 40 | Assert: K<1> Ex x (p(x) = T ^ ~K<1>~ p(x) = T) 41 | 42 | -------------------------------------------------------------------------------- /examples/tui/test-introspection-existential.limbo: -------------------------------------------------------------------------------- 1 | // Tests introspection with KB: p(c). 2 | 3 | Sort OBJ 4 | Var x -> OBJ 5 | Name n -> OBJ 6 | Fun c/0 -> OBJ 7 | 8 | Sort BOOL 9 | Fun p/1 -> BOOL 10 | Name T -> BOOL 11 | 12 | KB: p(c) = T 13 | 14 | Refute: K<0> Ex x p(x) = T 15 | Refute: M<0> Ex x p(x) = T 16 | Assert: K<1> Ex x p(x) = T 17 | Assert: M<1> Ex x p(x) = T 18 | 19 | Refute: Ex x K<0> p(x) = T 20 | Refute: Ex x M<0> p(x) = T 21 | Refute: Ex x K<1> p(x) = T 22 | Assert: Ex x M<1> p(x) = T 23 | 24 | Assert: Fa x ~ K<1> p(x) = T 25 | Assert: Fa x M<1> p(x) = T 26 | Assert: Fa x ~ K<1> p(x) /= T 27 | Assert: Fa x M<1> p(x) /= T 28 | 29 | Assert: K<1> Ex x (p(x) = T ^ M<1> p(x) /= T) 30 | Assert: K<1> Fa x (p(x) = T -> M<1> p(x) /= T) 31 | Assert: K<1> Ex x (p(x) = T ^ ~K<1>~ p(x) = T) 32 | 33 | -------------------------------------------------------------------------------- /examples/tui/test-parents-2.limbo: -------------------------------------------------------------------------------- 1 | Sort Human 2 | Name Sally, Mia, Frank, Fred -> Human 3 | Fun spouseOf/1, motherOf/1, fatherOf/1 -> Human 4 | Var x, y, z -> Human 5 | 6 | Rigid Sort Action 7 | Fun bear/2 -> Action 8 | Fun test/2 -> Action 9 | Var a -> Action 10 | 11 | Sort Result 12 | Name Yes -> Result 13 | Name No -> Result 14 | Var r -> Result 15 | Sensor Fun sf/Action -> Result 16 | 17 | 18 | Real: spouseOf(Mia) = Frank 19 | 20 | KB: spouseOf(Mia) = Frank v spouseOf(Mia) = Fred 21 | 22 | KB: [] [a] motherOf(x) = y <-> a = bear(y,x) v a /= bear(y,x) ^ motherOf(x) = y 23 | KB: [] [a] fatherOf(x) = y <-> ex z (a = bear(z,x) ^ spouseOf(z) = y) v fa z (a /= bear(z,x) ^ fatherOf(x) = y) 24 | 25 | // KB: [] sf(a) = r <-> (ex x ex y (a = test(x,y) ^ fatherOf(x) = y) -> r = Yes) ^ (~ ex x ex y (a = test(x,y) ^ fatherOf(x) = y) -> r = No) 26 | KB: [] sf(a) = r <-> ex x ex y (a = test(x,y) ^ fatherOf(x) = y ^ r = Yes) v fa x fa y (a /= test(x,y) v fatherOf(x) /= y) ^ r = No 27 | 28 | // KB: [] sf(test(y,x)) = r <-> (fatherOf(x) = y -> r = Yes) ^ (fatherOf(x) /= y -> r = No) 29 | // KB: [] sf(a) = r <-> r = r 30 | 31 | Assert: spouseOf(Mia) = Frank 32 | 33 | Assert: REG K<0> (spouseOf(Mia) = Frank v spouseOf(Mia) = Fred) 34 | Refute: REG K<2> (motherOf(Sally) = Mia) 35 | Refute: REG K<2> (fatherOf(Sally) = Frank v fatherOf(Sally) = Fred) 36 | Refute: REG ex x K<2> (spouseOf(Mia) = x) 37 | Assert: REG K<1> ex x (spouseOf(Mia) = x) 38 | 39 | Assert: REG [bear(Mia,Sally)] K<0> (motherOf(Sally) = Mia) 40 | Refute: REG [bear(Mia,Sally)] K<2> (motherOf(Sally) = Frank) 41 | Refute: REG [bear(Mia,Sally)] K<2> (motherOf(Sally) = Fred) 42 | Refute: REG [bear(Mia,Sally)] K<2> (spouseOf(Mia) = Frank) 43 | Refute: REG [bear(Mia,Sally)] K<2> (spouseOf(Mia) = Fred) 44 | Refute: REG [bear(Mia,Sally)] K<2> (fatherOf(Sally) = Frank) 45 | Assert: REG [bear(Mia,Sally)] M<1> (fatherOf(Sally) /= Frank) 46 | Assert: REG [bear(Mia,Sally)] M<2> (fatherOf(Sally) /= Frank) 47 | Refute: REG [bear(Mia,Sally)] K<2> (fatherOf(Sally) = Fred) 48 | Refute: REG [bear(Mia,Sally)] ex x K<2> (fatherOf(Sally) = x) 49 | Assert: REG [bear(Mia,Sally)] K<1> ex x (fatherOf(Sally) = x) 50 | Assert: REG K<1> [bear(Mia,Sally)] (fatherOf(Sally) = Frank v fatherOf(Sally) = Fred) 51 | Refute: REG [bear(Mia,Sally)] K<0> (fatherOf(Sally) = Frank v fatherOf(Sally) = Fred) 52 | Assert: REG [bear(Mia,Sally)] K<1> (fatherOf(Sally) = Frank v fatherOf(Sally) = Fred) 53 | 54 | Refute: REG sf(test(Sally,Frank)) = Yes 55 | Refute: REG sf(test(Sally,Frank)) = No 56 | Assert: REG [bear(Mia,Sally)] sf(test(Sally,Frank)) = Yes 57 | Refute: REG [bear(Mia,Sally)] sf(test(Sally,Frank)) = No 58 | 59 | Refute: REG [bear(Mia,Sally)] [test(Sally,Frank)] K<0> fatherOf(Sally) = Frank 60 | Assert: REG [bear(Mia,Sally)] [test(Sally,Frank)] K<1> fatherOf(Sally) = Frank 61 | Refute: REG [bear(Mia,Sally)] [test(Sally,Frank)] K<0> fatherOf(Sally) /= Fred 62 | Assert: REG [bear(Mia,Sally)] [test(Sally,Frank)] K<1> fatherOf(Sally) /= Fred 63 | Assert: REG [bear(Mia,Sally)] [test(Sally,Frank)] M<1> fatherOf(Sally) /= Fred 64 | 65 | Refute: REG [bear(Mia,Sally)] [test(Sally,Frank)] K<1> (fatherOf(Sally) = Frank ^ Yes /= Yes) 66 | 67 | Refute: REG [bear(Mia,Sally)] [test(Sally,Fred)] K<0> fatherOf(Sally) = Frank 68 | Assert: REG [bear(Mia,Sally)] [test(Sally,Fred)] K<1> fatherOf(Sally) = Frank 69 | Refute: REG [bear(Mia,Sally)] [test(Sally,Fred)] K<0> fatherOf(Sally) /= Fred 70 | Assert: REG [bear(Mia,Sally)] [test(Sally,Fred)] K<1> fatherOf(Sally) /= Fred 71 | 72 | -------------------------------------------------------------------------------- /examples/tui/test-parents.limbo: -------------------------------------------------------------------------------- 1 | Sort HUMAN 2 | Name Sally, Mia, Frank, Fred, Dummy -> HUMAN 3 | Fun spouseOf/1, motherOf/1, fatherOf/1 -> HUMAN 4 | Var x, y, z -> HUMAN 5 | 6 | Rigid Sort ACTION 7 | Fun bear/2 -> ACTION 8 | Fun test/1 -> ACTION 9 | Var a -> ACTION 10 | 11 | Sensor Fun sf/ACTION -> HUMAN 12 | 13 | Real: spouseOf(Mia) = Frank 14 | 15 | KB: spouseOf(Mia) = Frank v spouseOf(Mia) = Fred 16 | 17 | // KB: [] sf(a) = y <-> (a = test(Sally) ^ fatherOf(Sally) = y) v (a /= test(Sally) ^ y = Dummy) 18 | KB: [] sf(a) = y <-> ex x (a = test(x) ^ fatherOf(Sally) = y) v fa x (a /= test(x) ^ y = Dummy) 19 | // KB: [] sf(a) = y <-> fa x (a /= test(x)) 20 | //ex x (a = test(x) ^ fatherOf(x) = y) v fa x (a /= test(x) ^ y = Dummy) 21 | 22 | //KB: [] sf(a) = x <-> x=x 23 | 24 | KB: [] [a] motherOf(x) = y <-> a = bear(y,x) v a /= bear(y,x) ^ motherOf(x) = y 25 | KB: [] [a] fatherOf(x) = y <-> ex z (a = bear(z,x) ^ spouseOf(z) = y) v fa z (a /= bear(z,x) ^ fatherOf(x) = y) 26 | 27 | Refute: (K<1> Ex z (test(z) = bear(Mia,Sally))) 28 | 29 | Assert: spouseOf(Mia) = Frank 30 | 31 | Assert: REG K<0> (spouseOf(Mia) = Frank v spouseOf(Mia) = Fred) 32 | Refute: REG K<2> (motherOf(Sally) = Mia) 33 | Refute: REG K<2> (fatherOf(Sally) = Frank v fatherOf(Sally) = Fred) 34 | Refute: REG ex x K<2> (spouseOf(Mia) = x) 35 | Assert: REG K<1> ex x (spouseOf(Mia) = x) 36 | 37 | Assert: REG [bear(Mia,Sally)] K<0> (motherOf(Sally) = Mia) 38 | Refute: REG [bear(Mia,Sally)] K<1> (Fred /= Fred) 39 | 40 | Refute: REG [bear(Mia,Sally)] K<2> (motherOf(Sally) = Frank) 41 | Refute: REG [bear(Mia,Sally)] K<2> (motherOf(Sally) = Fred) 42 | Refute: REG [bear(Mia,Sally)] K<2> (fatherOf(Sally) = Frank) 43 | Refute: REG [bear(Mia,Sally)] K<2> (fatherOf(Sally) = Fred) 44 | Refute: REG [bear(Mia,Sally)] ex x K<2> (fatherOf(Sally) = x) 45 | Assert: REG [bear(Mia,Sally)] K<1> ex x (fatherOf(Sally) = x) 46 | Assert: REG K<1> [bear(Mia,Sally)] (fatherOf(Sally) = Frank v fatherOf(Sally) = Fred) 47 | Refute: REG [bear(Mia,Sally)] K<0> (fatherOf(Sally) = Frank v fatherOf(Sally) = Fred) 48 | Assert: REG [bear(Mia,Sally)] K<1> (fatherOf(Sally) = Frank v fatherOf(Sally) = Fred) 49 | 50 | Refute: REG [bear(Mia,Sally)] [test(Sally)] K<0> fatherOf(Sally) = Frank 51 | Assert: REG [bear(Mia,Sally)] [test(Sally)] K<2> fatherOf(Sally) = Frank 52 | Refute: REG [bear(Mia,Sally)] [test(Sally)] K<0> fatherOf(Sally) /= Fred 53 | Assert: REG [bear(Mia,Sally)] [test(Sally)] K<1> fatherOf(Sally) /= Fred 54 | 55 | Refute: REG [bear(Mia,Sally)] [test(Sally)] K<1> (fatherOf(Sally) = Frank ^ Dummy /= Dummy) 56 | 57 | Refute: REG [bear(Mia,Sally)] [test(Sally)] K<0> fatherOf(Sally) = Frank 58 | Assert: REG [bear(Mia,Sally)] [test(Sally)] K<1> fatherOf(Sally) = Frank 59 | Refute: REG [bear(Mia,Sally)] [test(Sally)] K<0> fatherOf(Sally) /= Fred 60 | Assert: REG [bear(Mia,Sally)] [test(Sally)] K<1> fatherOf(Sally) /= Fred 61 | 62 | -------------------------------------------------------------------------------- /examples/tui/test-propositions.limbo: -------------------------------------------------------------------------------- 1 | // Simulate propositions with boolean functions. 2 | 3 | Sort BOOL 4 | 5 | Name T -> BOOL 6 | Fun p/0 -> BOOL 7 | Fun q/0 -> BOOL 8 | 9 | Let P := p == T 10 | Let Q := q == T 11 | // Now we can use P and Q like propositional atoms in our query. 12 | 13 | Refute: Know<2> !P 14 | Refute: G Know<2> !P 15 | Refute: Know<2> P 16 | Refute: G Know<2> P 17 | Assert: Know<0> (P || !P) // because of Clause::valid() 18 | Assert: G Know<0> (P || !P) // because of Clause::valid() 19 | Assert: Know<1> (P || !P) 20 | Assert: G Know<1> (P || !P) 21 | 22 | Let phi := (P || !P) && (Q || !Q) 23 | Assert: Know<1> phi // because the conjunction is resolved before splitting 24 | Assert: G Know<1> phi // because the conjunction is resolved before splitting 25 | Assert: Know<2> phi 26 | Assert: G Know<2> phi 27 | 28 | Let phi := P && Q || P && !Q || !P && Q || !P && !Q 29 | Refute: Know<1> phi 30 | Refute: G Know<1> phi 31 | Assert: Know<2> phi 32 | Assert: G Know<2> phi 33 | 34 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-1.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,fa(x2,ex(x3,fa(x4, (x1 v x2)^ (~x2 v x3)^ (x1 v ~x3))))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x3/0, x3'/0 -> Bool 7 | Fun x2/0 -> Bool 8 | Fun x4/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x3=T -> p=T 69 | KB: ~x3'=T -> p=T 70 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 71 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 72 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 73 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 79 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 80 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 81 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 82 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 83 | Refute: K<3> O 84 | Assert: K<4> O 85 | Assert: K<4> (O ^ (~p=T -> ((x1=T v x2=T)^ (~x2=T v x3=T)^ (x1=T v x3'=T)))) 86 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-10.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,ex(x2,ex(x3,ex(x4,x4^ ~x1^ ~x2^ ~x3^ ~x4)))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x2/0, x2'/0 -> Bool 7 | Fun x3/0, x3'/0 -> Bool 8 | Fun x4/0, x4'/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x2=T -> p=T 69 | KB: ~x2'=T -> p=T 70 | KB: ~x3=T -> p=T 71 | KB: ~x3'=T -> p=T 72 | KB: ~x4=T -> p=T 73 | KB: ~x4'=T -> p=T 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 79 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 80 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 81 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 82 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'3=T -> O 83 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'4=T -> O 84 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ s2'3=T ^ s2'4=T -> O 85 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'3=T -> O 86 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'4=T -> O 87 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ s2'3=T ^ s2'4=T -> O 88 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 89 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 90 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 91 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 92 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> O 93 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4'=T -> O 94 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 95 | Refute: K<3> O 96 | Assert: K<4> O 97 | Refute: K<4> (O ^ (~p=T -> (x4=T^x1'=T^x2'=T^x3'=T^x4'=T))) 98 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-11.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,fa(x2,ex(x3,fa(x4, (~x1 v x2)^ (~x2 v x3)^ (~x1 v ~x3)^ ~x1)))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x3/0, x3'/0 -> Bool 7 | Fun x2/0 -> Bool 8 | Fun x4/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x3=T -> p=T 69 | KB: ~x3'=T -> p=T 70 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 71 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 72 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 73 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 79 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 80 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 81 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 82 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 83 | Refute: K<3> O 84 | Assert: K<4> O 85 | Assert: K<4> (O ^ (~p=T -> ((x1'=T v x2=T)^ (~x2=T v x3=T)^ (x1'=T v x3'=T)^x1'=T))) 86 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-12.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,ex(x2,ex(x3,ex(x4,x4^ ~x4)))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x2/0, x2'/0 -> Bool 7 | Fun x3/0, x3'/0 -> Bool 8 | Fun x4/0, x4'/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x2=T -> p=T 69 | KB: ~x2'=T -> p=T 70 | KB: ~x3=T -> p=T 71 | KB: ~x3'=T -> p=T 72 | KB: ~x4=T -> p=T 73 | KB: ~x4'=T -> p=T 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 79 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 80 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 81 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 82 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'3=T -> O 83 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'4=T -> O 84 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ s2'3=T ^ s2'4=T -> O 85 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'3=T -> O 86 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'4=T -> O 87 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ s2'3=T ^ s2'4=T -> O 88 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 89 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 90 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 91 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 92 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> O 93 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4'=T -> O 94 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 95 | Refute: K<3> O 96 | Assert: K<4> O 97 | Refute: K<4> (O ^ (~p=T -> (x4=T^x4'=T))) 98 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-13.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,ex(x2,ex(x3,ex(x4,x1^x2^x3^x4)))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x2/0, x2'/0 -> Bool 7 | Fun x3/0, x3'/0 -> Bool 8 | Fun x4/0, x4'/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x2=T -> p=T 69 | KB: ~x2'=T -> p=T 70 | KB: ~x3=T -> p=T 71 | KB: ~x3'=T -> p=T 72 | KB: ~x4=T -> p=T 73 | KB: ~x4'=T -> p=T 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 79 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 80 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 81 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 82 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'3=T -> O 83 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'4=T -> O 84 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ s2'3=T ^ s2'4=T -> O 85 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'3=T -> O 86 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'4=T -> O 87 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ s2'3=T ^ s2'4=T -> O 88 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 89 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 90 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 91 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 92 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> O 93 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4'=T -> O 94 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 95 | Refute: K<3> O 96 | Assert: K<4> O 97 | Assert: K<4> (O ^ (~p=T -> (x1=T^x2=T^x3=T^x4=T))) 98 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-14.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,x1) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun o1/0, o2/0 -> Bool 7 | Fun u0'1/0, u0'2/0 -> Bool 8 | Fun u1'1/0, u1'2/0 -> Bool 9 | Fun s1'1/0 -> Bool 10 | Fun p/0 -> Bool 11 | Let O := o1=T v o2=T 12 | KB: u0'1=T 13 | KB: u0'2=T 14 | KB: u0'1=T ^ u0'2=T ^ x1=T -> u1'1=T 15 | KB: u0'1=T ^ u0'2=T ^ x1=T -> u1'2=T 16 | KB: u0'1=T ^ u0'2=T ^ x1'=T -> u1'1=T 17 | KB: u0'1=T ^ u0'2=T ^ x1'=T -> u1'2=T 18 | KB: ~x1=T -> p=T 19 | KB: ~x1'=T -> p=T 20 | KB: u0'1=T ^ u0'2=T ^ ~x1=T -> O 21 | KB: u0'1=T ^ u0'2=T ^ ~x1'=T -> O 22 | KB: u1'1=T ^ u1'2=T -> O 23 | Refute: K<0> O 24 | Assert: K<1> O 25 | Assert: K<1> (O ^ (~p=T -> (x1=T))) 26 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-15.limbo: -------------------------------------------------------------------------------- 1 | // fa(x1,x1 v ~x1) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0 -> Bool 6 | Fun o1/0, o2/0 -> Bool 7 | Fun u0'1/0, u0'2/0 -> Bool 8 | Fun u1'1/0, u1'2/0 -> Bool 9 | Fun s1'1/0 -> Bool 10 | Fun p/0 -> Bool 11 | Let O := o1=T v o2=T 12 | KB: u0'1=T 13 | KB: u0'2=T 14 | KB: u0'1=T ^ u0'2=T ^ x1=T -> u1'1=T 15 | KB: u0'1=T ^ u0'2=T ^ x1=T -> u1'2=T 16 | KB: u0'1=T ^ u0'2=T ^ ~x1=T -> u1'1=T 17 | KB: u0'1=T ^ u0'2=T ^ ~x1=T -> u1'2=T 18 | KB: u1'1=T ^ u1'2=T -> O 19 | Refute: K<0> O 20 | Assert: K<1> O 21 | Assert: K<1> (O ^ (~p=T -> (x1=T v ~x1=T))) 22 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-16.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,ex(x2,x1^x2)) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x2/0, x2'/0 -> Bool 7 | Fun o1/0, o2/0, o3/0 -> Bool 8 | Fun u0'1/0, u0'2/0, u0'3/0 -> Bool 9 | Fun u1'1/0, u1'2/0, u1'3/0 -> Bool 10 | Fun u2'1/0, u2'2/0, u2'3/0 -> Bool 11 | Fun s1'2/0 -> Bool 12 | Fun s2'2/0 -> Bool 13 | Fun p/0 -> Bool 14 | Let O := o1=T v o2=T v o3=T 15 | KB: u0'1=T 16 | KB: u0'2=T 17 | KB: u0'3=T 18 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ x1=T -> u1'1=T 19 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ x1=T -> u1'2=T 20 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ x1=T -> u1'3=T 21 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ x1'=T -> u1'1=T 22 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ x1'=T -> u1'2=T 23 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ x1'=T -> u1'3=T 24 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ x2=T -> u2'1=T 25 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ x2=T -> u2'2=T 26 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ x2=T -> u2'3=T 27 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ x2'=T -> u2'1=T 28 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ x2'=T -> u2'2=T 29 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ x2'=T -> u2'3=T 30 | KB: ~x1=T -> p=T 31 | KB: ~x1'=T -> p=T 32 | KB: ~x2=T -> p=T 33 | KB: ~x2'=T -> p=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ ~x1=T ^ ~s1'2=T -> O 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ ~x1=T ^ s1'2=T -> O 36 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ ~x1'=T ^ ~s1'2=T -> O 37 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ ~x1'=T ^ s1'2=T -> O 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ ~x2=T -> O 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ ~x2'=T -> O 40 | KB: u2'1=T ^ u2'2=T ^ u2'3=T -> O 41 | Refute: K<1> O 42 | Assert: K<2> O 43 | Assert: K<2> (O ^ (~p=T -> (x1=T^x2=T))) 44 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-17.limbo: -------------------------------------------------------------------------------- 1 | // fa(x1,fa(x2, (x1 v ~x1)^ (x2 v ~x2))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0 -> Bool 6 | Fun x2/0 -> Bool 7 | Fun o1/0, o2/0, o3/0 -> Bool 8 | Fun u0'1/0, u0'2/0, u0'3/0 -> Bool 9 | Fun u1'1/0, u1'2/0, u1'3/0 -> Bool 10 | Fun u2'1/0, u2'2/0, u2'3/0 -> Bool 11 | Fun s1'2/0 -> Bool 12 | Fun s2'2/0 -> Bool 13 | Fun p/0 -> Bool 14 | Let O := o1=T v o2=T v o3=T 15 | KB: u0'1=T 16 | KB: u0'2=T 17 | KB: u0'3=T 18 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ x1=T -> u1'1=T 19 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ x1=T -> u1'2=T 20 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ x1=T -> u1'3=T 21 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ ~x1=T -> u1'1=T 22 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ ~x1=T -> u1'2=T 23 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ ~x1=T -> u1'3=T 24 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ x2=T -> u2'1=T 25 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ x2=T -> u2'2=T 26 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ x2=T -> u2'3=T 27 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ ~x2=T -> u2'1=T 28 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ ~x2=T -> u2'2=T 29 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ ~x2=T -> u2'3=T 30 | KB: u2'1=T ^ u2'2=T ^ u2'3=T -> O 31 | Refute: K<1> O 32 | Assert: K<2> O 33 | Assert: K<2> (O ^ (~p=T -> ((x1=T v ~x1=T)^ (x2=T v ~x2=T)))) 34 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-2.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,fa(x2,ex(x3,fa(x4, (x1 v x2)^ (~x2 v x3)^ (x1 v ~x3)^ (x2 v ~x4))))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x3/0, x3'/0 -> Bool 7 | Fun x2/0 -> Bool 8 | Fun x4/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x3=T -> p=T 69 | KB: ~x3'=T -> p=T 70 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 71 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 72 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 73 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 79 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 80 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 81 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 82 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 83 | Refute: K<3> O 84 | Assert: K<4> O 85 | Refute: K<4> (O ^ (~p=T -> ((x1=T v x2=T)^ (~x2=T v x3=T)^ (x1=T v x3'=T)^ (x2=T v ~x4=T)))) 86 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-3.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,fa(x2,ex(x3,fa(x4, (x1 v x2)^ (~x2 v x3)^ (x1 v ~x3)^ (x2 v ~x3))))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x3/0, x3'/0 -> Bool 7 | Fun x2/0 -> Bool 8 | Fun x4/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x3=T -> p=T 69 | KB: ~x3'=T -> p=T 70 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 71 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 72 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 73 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 79 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 80 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 81 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 82 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 83 | Refute: K<3> O 84 | Assert: K<4> O 85 | Assert: K<4> (O ^ (~p=T -> ((x1=T v x2=T)^ (~x2=T v x3=T)^ (x1=T v x3'=T)^ (x2=T v x3'=T)))) 86 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-4.limbo: -------------------------------------------------------------------------------- 1 | // fa(x1,fa(x2,fa(x3,x1^x2^x3 v x1^x2^ ~x3 v x1^ ~x2^x3 v x1^ ~x2^ ~x3 v ~x1^x2^x3 v ~x1^x2^ ~x3 v ~x1^ ~x2^x3 v ~x1^ ~x2^ ~x3))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0 -> Bool 6 | Fun x2/0 -> Bool 7 | Fun x3/0 -> Bool 8 | Fun o1/0, o2/0, o3/0, o4/0 -> Bool 9 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0 -> Bool 10 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0 -> Bool 11 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0 -> Bool 12 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0 -> Bool 13 | Fun s1'2/0, s1'3/0 -> Bool 14 | Fun s2'3/0 -> Bool 15 | Fun s3'3/0 -> Bool 16 | Fun p/0 -> Bool 17 | Let O := o1=T v o2=T v o3=T v o4=T 18 | KB: u0'1=T 19 | KB: u0'2=T 20 | KB: u0'3=T 21 | KB: u0'4=T 22 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ x1=T -> u1'1=T 23 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ x1=T -> u1'2=T 24 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ x1=T -> u1'3=T 25 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ x1=T -> u1'4=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ ~x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ ~x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ ~x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ ~x1=T -> u1'4=T 30 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ x2=T -> u2'1=T 31 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ x2=T -> u2'2=T 32 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ x2=T -> u2'3=T 33 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ x2=T -> u2'4=T 34 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ ~x2=T -> u2'1=T 35 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ ~x2=T -> u2'2=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ ~x2=T -> u2'3=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ ~x2=T -> u2'4=T 38 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ x3=T -> u3'1=T 39 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ x3=T -> u3'2=T 40 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ x3=T -> u3'3=T 41 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ x3=T -> u3'4=T 42 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ ~x3=T -> u3'1=T 43 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ ~x3=T -> u3'2=T 44 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ ~x3=T -> u3'3=T 45 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ ~x3=T -> u3'4=T 46 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T -> O 47 | Refute: K<2> O 48 | Assert: K<3> O 49 | Assert: K<3> (O ^ (~p=T -> (x1=T^x2=T^x3=T v x1=T^x2=T^ ~x3=T v x1=T^ ~x2=T^x3=T v x1=T^ ~x2=T^ ~x3=T v ~x1=T^x2=T^x3=T v ~x1=T^x2=T^ ~x3=T v ~x1=T^ ~x2=T^x3=T v ~x1=T^ ~x2=T^ ~x3=T))) 50 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-5.limbo: -------------------------------------------------------------------------------- 1 | // fa(x1,fa(x2,fa(x3,fa(x4,x4 v ~x4)))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0 -> Bool 6 | Fun x2/0 -> Bool 7 | Fun x3/0 -> Bool 8 | Fun x4/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'5=T 66 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 67 | Refute: K<3> O 68 | Assert: K<4> O 69 | Assert: K<4> (O ^ (~p=T -> (x4=T v ~x4=T))) 70 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-6.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,ex(x2,ex(x3,ex(x4,x1^x2^x3^x4)))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x2/0, x2'/0 -> Bool 7 | Fun x3/0, x3'/0 -> Bool 8 | Fun x4/0, x4'/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x2=T -> p=T 69 | KB: ~x2'=T -> p=T 70 | KB: ~x3=T -> p=T 71 | KB: ~x3'=T -> p=T 72 | KB: ~x4=T -> p=T 73 | KB: ~x4'=T -> p=T 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 79 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 80 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 81 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 82 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'3=T -> O 83 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'4=T -> O 84 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ s2'3=T ^ s2'4=T -> O 85 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'3=T -> O 86 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'4=T -> O 87 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ s2'3=T ^ s2'4=T -> O 88 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 89 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 90 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 91 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 92 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> O 93 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4'=T -> O 94 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 95 | Refute: K<3> O 96 | Assert: K<4> O 97 | Assert: K<4> (O ^ (~p=T -> (x1=T^x2=T^x3=T^x4=T))) 98 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-7.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,ex(x2,ex(x3,ex(x4,~x1^ ~x2^ ~x3^ ~x4)))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x2/0, x2'/0 -> Bool 7 | Fun x3/0, x3'/0 -> Bool 8 | Fun x4/0, x4'/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x2=T -> p=T 69 | KB: ~x2'=T -> p=T 70 | KB: ~x3=T -> p=T 71 | KB: ~x3'=T -> p=T 72 | KB: ~x4=T -> p=T 73 | KB: ~x4'=T -> p=T 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 79 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 80 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 81 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 82 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'3=T -> O 83 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'4=T -> O 84 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ s2'3=T ^ s2'4=T -> O 85 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'3=T -> O 86 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'4=T -> O 87 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ s2'3=T ^ s2'4=T -> O 88 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 89 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 90 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 91 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 92 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> O 93 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4'=T -> O 94 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 95 | Refute: K<3> O 96 | Assert: K<4> O 97 | Assert: K<4> (O ^ (~p=T -> (x1'=T^x2'=T^x3'=T^x4'=T))) 98 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-8.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,fa(x2,ex(x3,fa(x4, (~x1 v x2)^ (~x2 v x3)^ (~x1 v ~x3)^ ~x1)))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x3/0, x3'/0 -> Bool 7 | Fun x2/0 -> Bool 8 | Fun x4/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x3=T -> p=T 69 | KB: ~x3'=T -> p=T 70 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 71 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 72 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 73 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 79 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 80 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 81 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 82 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 83 | Refute: K<3> O 84 | Assert: K<4> O 85 | Assert: K<4> (O ^ (~p=T -> ((x1'=T v x2=T)^ (~x2=T v x3=T)^ (x1'=T v x3'=T)^x1'=T))) 86 | -------------------------------------------------------------------------------- /examples/tui/test-qbf-9.limbo: -------------------------------------------------------------------------------- 1 | // ex(x1,ex(x2,ex(x3,ex(x4,x1^ ~x1^ ~x2^ ~x3^ ~x4)))) 2 | Call: disable_distribute() 3 | Sort Bool 4 | Name T, X -> Bool 5 | Fun x1/0, x1'/0 -> Bool 6 | Fun x2/0, x2'/0 -> Bool 7 | Fun x3/0, x3'/0 -> Bool 8 | Fun x4/0, x4'/0 -> Bool 9 | Fun o1/0, o2/0, o3/0, o4/0, o5/0 -> Bool 10 | Fun u0'1/0, u0'2/0, u0'3/0, u0'4/0, u0'5/0 -> Bool 11 | Fun u1'1/0, u1'2/0, u1'3/0, u1'4/0, u1'5/0 -> Bool 12 | Fun u2'1/0, u2'2/0, u2'3/0, u2'4/0, u2'5/0 -> Bool 13 | Fun u3'1/0, u3'2/0, u3'3/0, u3'4/0, u3'5/0 -> Bool 14 | Fun u4'1/0, u4'2/0, u4'3/0, u4'4/0, u4'5/0 -> Bool 15 | Fun s1'2/0, s1'3/0, s1'4/0 -> Bool 16 | Fun s2'3/0, s2'4/0 -> Bool 17 | Fun s3'4/0 -> Bool 18 | Fun s4'4/0 -> Bool 19 | Fun p/0 -> Bool 20 | Let O := o1=T v o2=T v o3=T v o4=T v o5=T 21 | KB: u0'1=T 22 | KB: u0'2=T 23 | KB: u0'3=T 24 | KB: u0'4=T 25 | KB: u0'5=T 26 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'1=T 27 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'2=T 28 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'3=T 29 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'4=T 30 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1=T -> u1'5=T 31 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'1=T 32 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'2=T 33 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'3=T 34 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'4=T 35 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ x1'=T -> u1'5=T 36 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'1=T 37 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'2=T 38 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'3=T 39 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'4=T 40 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2=T -> u2'5=T 41 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'1=T 42 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'2=T 43 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'3=T 44 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'4=T 45 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ x2'=T -> u2'5=T 46 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'1=T 47 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'2=T 48 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'3=T 49 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'4=T 50 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3=T -> u3'5=T 51 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'1=T 52 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'2=T 53 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'3=T 54 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'4=T 55 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ x3'=T -> u3'5=T 56 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'1=T 57 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'2=T 58 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'3=T 59 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'4=T 60 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4=T -> u4'5=T 61 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'1=T 62 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'2=T 63 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'3=T 64 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'4=T 65 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ x4'=T -> u4'5=T 66 | KB: ~x1=T -> p=T 67 | KB: ~x1'=T -> p=T 68 | KB: ~x2=T -> p=T 69 | KB: ~x2'=T -> p=T 70 | KB: ~x3=T -> p=T 71 | KB: ~x3'=T -> p=T 72 | KB: ~x4=T -> p=T 73 | KB: ~x4'=T -> p=T 74 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'2=T -> O 75 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'3=T -> O 76 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ ~s1'4=T -> O 77 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 78 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'2=T -> O 79 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'3=T -> O 80 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ ~s1'4=T -> O 81 | KB: u0'1=T ^ u0'2=T ^ u0'3=T ^ u0'4=T ^ u0'5=T ^ ~x1'=T ^ s1'2=T ^ s1'3=T ^ s1'4=T -> O 82 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'3=T -> O 83 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ ~s2'4=T -> O 84 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2=T ^ s2'3=T ^ s2'4=T -> O 85 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'3=T -> O 86 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ ~s2'4=T -> O 87 | KB: u1'1=T ^ u1'2=T ^ u1'3=T ^ u1'4=T ^ u1'5=T ^ ~x2'=T ^ s2'3=T ^ s2'4=T -> O 88 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ ~s3'4=T -> O 89 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3=T ^ s3'4=T -> O 90 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ ~s3'4=T -> O 91 | KB: u2'1=T ^ u2'2=T ^ u2'3=T ^ u2'4=T ^ u2'5=T ^ ~x3'=T ^ s3'4=T -> O 92 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4=T -> O 93 | KB: u3'1=T ^ u3'2=T ^ u3'3=T ^ u3'4=T ^ u3'5=T ^ ~x4'=T -> O 94 | KB: u4'1=T ^ u4'2=T ^ u4'3=T ^ u4'4=T ^ u4'5=T -> O 95 | Refute: K<3> O 96 | Assert: K<4> O 97 | Refute: K<4> (O ^ (~p=T -> (x1=T^x1'=T^x2'=T^x3'=T^x4'=T))) 98 | -------------------------------------------------------------------------------- /examples/tui/test-rich-father.limbo: -------------------------------------------------------------------------------- 1 | // Are Frank or Fred rich? 2 | 3 | Sort HUMAN 4 | Sort BOOL 5 | 6 | Variable x -> HUMAN 7 | Variable y -> HUMAN 8 | Variable z -> HUMAN 9 | 10 | Name Frank -> HUMAN 11 | Name Fred -> HUMAN 12 | Name Sally -> HUMAN 13 | Name T -> BOOL 14 | 15 | Function fatherOf/1 -> HUMAN 16 | Function rich/1 -> BOOL 17 | 18 | KB: rich(fatherOf(Sally)) = T 19 | KB: fatherOf(Sally) = Frank v fatherOf(Sally) = Fred 20 | 21 | // It's explicit knowledge that Frank/Fred is the father, then Frank is rich. Same for Fred. 22 | Assert: K<0> (fatherOf(Sally) = Frank -> rich(Frank) = T) 23 | Assert: K<0> (fatherOf(Sally) = Fred -> rich(Fred) = T) 24 | Refute: K<0> (fatherOf(Sally) = Frank -> rich(Fred) = T) 25 | 26 | // At split level 1, it is believed that that Frank or Fred are rich. 27 | Refute: K<0> (rich(Frank) = T v rich(Fred) = T) 28 | Assert: K<1> (rich(Frank) = T v rich(Fred) = T) 29 | 30 | // At split level 1, it is considered possible that Frank is the father. Same for Fred. 31 | Refute: M<0> (fatherOf(Sally) = Frank) 32 | Refute: M<0> (fatherOf(Sally) = Fred) 33 | Assert: M<1> (fatherOf(Sally) = Frank) 34 | Assert: M<1> (fatherOf(Sally) = Fred) 35 | 36 | // At split level 1, it is considered possible that Frank is rich. Same for Fred. 37 | Refute: M<0> (rich(Frank) = T) 38 | Assert: M<1> (rich(Frank) = T) 39 | Assert: M<1> (rich(Fred) = T) 40 | 41 | // We know Sally's father is rich, but we don't know who it is. 42 | Refute: K<1> ex x (fatherOf(Sally) = x ^ rich(x) = T ^ K<2> fatherOf(Sally) = x) 43 | Refute: K<1> ex x (fatherOf(Sally) = x ^ rich(x) = T ^ K<2> fatherOf(Sally) /= x) 44 | Assert: K<1> ex x (fatherOf(Sally) = x ^ rich(x) = T ^ ~K<1> fatherOf(Sally) /= x) 45 | Assert: K<1> ex x (fatherOf(Sally) = x ^ rich(x) = T ^ M<1> fatherOf(Sally) /= x) 46 | 47 | -------------------------------------------------------------------------------- /examples/tui/test-siblings.limbo: -------------------------------------------------------------------------------- 1 | // Are Sally and Sonny siblings? 2 | 3 | Sort HUMAN 4 | Sort BOOL 5 | 6 | Variable x -> HUMAN 7 | Variable y -> HUMAN 8 | Variable z -> HUMAN 9 | 10 | Name Mary -> HUMAN 11 | Name Mia -> HUMAN 12 | Name Frank -> HUMAN 13 | Name Fred -> HUMAN 14 | Name Sally -> HUMAN 15 | Name Sonny -> HUMAN 16 | Name T -> BOOL 17 | 18 | Function fatherOf/1 -> HUMAN 19 | Function motherOf/1 -> HUMAN 20 | Function siblings/2 -> BOOL 21 | 22 | // Sally's parents are Frank and either Mary or Mia. 23 | KB: motherOf(Sally) == Mary || motherOf(Sally) == Mia 24 | KB: fatherOf(Sally) == Frank 25 | 26 | // Sonny's parents are Mary and either Frank or Fred. 27 | KB: motherOf(Sonny) == Mary 28 | KB: fatherOf(Sonny) == Frank || fatherOf(Sonny) == Fred 29 | 30 | // When x and y have they same mother or father, they are siblings. 31 | KB: x != y && motherOf(x) == motherOf(y) -> siblings(x, y) == T 32 | KB: x != y && fatherOf(x) == fatherOf(y) -> siblings(x, y) == T 33 | KB: siblings(x, y) == siblings(y, x) 34 | 35 | // Mother and father of any person are not siblings. 36 | KB: siblings(motherOf(z), fatherOf(z)) != T 37 | 38 | // Mia and Frank or Mary and Fred are siblings. 39 | KB: siblings(Mia, Frank) == T || siblings(Mary, Fred) == T 40 | 41 | // If Mia and Frank are siblings, they cannot have Sally together, so Sally's 42 | // mother must be Mary. Mary is also Sonny's mother, so they're siblings. 43 | // If Mary and Fred are siblings, they cannot have Sonny together, so Sonny's 44 | // father must be Frank. Frank is also Sally's father, so they're siblings. 45 | Refute: Know<0> siblings(Sally, Sonny) == T 46 | Refute: G Know<0> siblings(Sally, Sonny) == T 47 | Assert: Know<1> siblings(Sally, Sonny) == T 48 | Assert: G Know<1> siblings(Sally, Sonny) == T 49 | 50 | Assert: Know<0> Fa x siblings(motherOf(x), fatherOf(x)) != T 51 | Assert: G Know<0> Fa x siblings(motherOf(x), fatherOf(x)) != T 52 | Assert: Know<0> ~ Ex x ~ Fa y Fa z (motherOf(x) == y && fatherOf(x) == z -> siblings(y,z) != T) 53 | Assert: G Know<0> ~ Ex x ~ Fa y Fa z (motherOf(x) == y && fatherOf(x) == z -> siblings(y,z) != T) 54 | // Requires reflexivity of siblings/2: 55 | Refute: Know<0> ~ Ex x ~ Fa y Fa z (motherOf(x) == y && fatherOf(x) == z -> siblings(z,y) != T) 56 | Refute: G Know<0> ~ Ex x ~ Fa y Fa z (motherOf(x) == y && fatherOf(x) == z -> siblings(z,y) != T) 57 | Assert: Know<1> ~ Ex x ~ Fa y Fa z (motherOf(x) == y && fatherOf(x) == z -> siblings(z,y) != T) 58 | Assert: G Know<1> ~ Ex x ~ Fa y Fa z (motherOf(x) == y && fatherOf(x) == z -> siblings(z,y) != T) 59 | 60 | -------------------------------------------------------------------------------- /examples/tui/test-unknown-father.limbo: -------------------------------------------------------------------------------- 1 | // Unclear father: is Jesu father God or Joseph? 2 | // Maybe the test is a bit unfortunate. 3 | 4 | Sort ENTITY 5 | Sort BOOL 6 | 7 | Variable x -> ENTITY 8 | Variable y -> ENTITY 9 | 10 | Name Jesus -> ENTITY 11 | Name Mary -> ENTITY 12 | Name Joe -> ENTITY 13 | Name HolyGhost -> ENTITY 14 | Name God -> ENTITY 15 | Name True -> BOOL 16 | 17 | Function fatherOf/1 -> ENTITY 18 | Function motherOf/1 -> ENTITY 19 | Function is_mortal/1 -> BOOL 20 | 21 | KB: Mary == motherOf(Jesus) 22 | KB: HolyGhost == fatherOf(Jesus) || God == fatherOf(Jesus) || Joe == fatherOf(Jesus) 23 | KB: is_mortal(Mary) == True 24 | KB: is_mortal(Joe) == True 25 | KB: fatherOf(Jesus) != Joe -> is_mortal(fatherOf(Jesus)) != True 26 | // An alternative way to state the previous clause: 27 | // KB: (fatherOf(Jesus) != x || x == Joe || is_mortal(x) != True 28 | 29 | Let phi := HolyGhost == fatherOf(Jesus) || God == fatherOf(Jesus) || Joe == fatherOf(Jesus) 30 | Assert: Know<0> phi 31 | Assert: G Know<0> phi 32 | 33 | Let phi := Ex x (x == fatherOf(Jesus)) 34 | Refute: Know<0> phi 35 | Refute: G Know<0> phi 36 | Assert: Know<1> phi 37 | Assert: G Know<1> phi 38 | 39 | Let phi := HolyGhost == fatherOf(Jesus) 40 | Refute: Cons<0> phi 41 | Refute: G Cons<0> phi 42 | Assert: Cons<1> phi 43 | Assert: G Cons<1> phi 44 | 45 | Let phi := HolyGhost == fatherOf(Jesus) && God == fatherOf(Jesus) || Joe == fatherOf(Jesus) 46 | Refute: G Know<0> phi 47 | 48 | Let phi := motherOf(Jesus) == fatherOf(Jesus) 49 | Refute: Know<0> phi 50 | Refute: G Know<0> phi 51 | Refute: Cons<0> phi 52 | Refute: G Cons<0> phi 53 | Assert: Know<0> !phi 54 | Assert: G Know<0> !phi 55 | Refute: Cons<0> !phi 56 | Refute: G Cons<0> !phi 57 | Assert: Cons<1> !phi 58 | Assert: G Cons<1> !phi 59 | 60 | Assert: G Know<0> is_mortal(motherOf(Jesus)) == True 61 | 62 | Let phi := is_mortal(fatherOf(Jesus)) == True 63 | Assert: Cons<1> phi 64 | Assert: G Cons<1> phi 65 | Assert: Cons<1> !phi 66 | Assert: G Cons<1> !phi 67 | 68 | Assert: Know<1> Ex x is_mortal(x) == True 69 | Assert: G Know<1> Ex x is_mortal(x) == True 70 | Refute: Know<1> Fa x is_mortal(x) == True 71 | Refute: G Know<1> Fa x is_mortal(x) == True 72 | 73 | -------------------------------------------------------------------------------- /examples/tui/test-veggie-with-guarantee.limbo: -------------------------------------------------------------------------------- 1 | // If she's not Italian, is she a Vegatarian? 2 | // With consistency guarantee. 3 | 4 | Sort FOOD 5 | Sort BOOL 6 | 7 | Name T -> BOOL 8 | Name roo -> FOOD 9 | 10 | Var x -> FOOD 11 | 12 | Fun Aussie/0 -> BOOL 13 | Fun Italian/0 -> BOOL 14 | Fun Eats/1 -> BOOL 15 | Fun Meat/1 -> BOOL 16 | Fun Veggie/0 -> BOOL 17 | 18 | Let falsum := T /= T 19 | Let truth := ~falsum 20 | 21 | // The following conditionals are all the agent believes. In the formal logic, 22 | // there is just one pair of split levels for this only-believing. In this 23 | // implementation, there is one such pair of split levels per each conditional. 24 | // The only reason for this departure from the theory is that it was a little 25 | // less work to implement. 26 | 27 | // Most Aussies are not Italian, and vice-versa. 28 | KB: G Bel<1,1> Aussie = T ==> Italian != T 29 | KB: G Bel<1,1> Italian = T ==> Aussie != T 30 | 31 | // Most Aussies eat Kangaroo meat. 32 | KB: G Bel<1,1> Aussie = T ==> Eats(roo) = T 33 | 34 | // She's presumably Italian or a Vegetarian, and 35 | // if she's not Italian, she's probably Australian. 36 | KB: G Bel<1,1> truth ==> (Italian = T || Veggie = T) 37 | KB: G Bel<1,1> Italian != T ==> Aussie = T 38 | 39 | // Kangaroo is definitely meat, and Vegetarians don't eat meat. 40 | KB: G Bel<1,1> Meat(roo) != T ==> falsum 41 | KB: G Bel<1,1> ~Fa x ((Veggie == T && Meat(x) == T) -> Eats(x) != T) ==> falsum 42 | 43 | 44 | // The question is now: 45 | // If she's not Italian, is she a Vegetarian? 46 | // We find that out at belief levels 1, 1. 47 | Refute: G Bel<0,0> Italian != T ==> Veggie != T 48 | Refute: G Bel<0,1> Italian != T ==> Veggie != T 49 | Refute: G Bel<1,0> Italian != T ==> Veggie != T 50 | Assert: G Bel<1,1> Italian != T ==> Veggie != T 51 | 52 | -------------------------------------------------------------------------------- /examples/tui/test-veggie.limbo: -------------------------------------------------------------------------------- 1 | // If she's not Italian, is she a Vegatarian? 2 | // Without consistency guarantee. 3 | 4 | Sort FOOD 5 | Sort BOOL 6 | 7 | Name T -> BOOL 8 | Name roo -> FOOD 9 | 10 | Var x -> FOOD 11 | 12 | Fun Aussie/0 -> BOOL 13 | Fun Italian/0 -> BOOL 14 | Fun Eats/1 -> BOOL 15 | Fun Meat/1 -> BOOL 16 | Fun Veggie/0 -> BOOL 17 | 18 | Let falsum := T /= T 19 | Let truth := ~falsum 20 | 21 | // The following conditionals are all the agent believes. In the formal logic, 22 | // there is just one pair of split levels for this only-believing. In this 23 | // implementation, there is one such pair of split levels per each conditional. 24 | // The only reason for this departure from the theory is that it was a little 25 | // less work to implement. 26 | 27 | // Most Aussies are not Italian, and vice-versa. 28 | KB: Bel<1,1> Aussie = T ==> Italian != T 29 | KB: Bel<1,1> Italian = T ==> Aussie != T 30 | 31 | // Most Aussies eat Kangaroo meat. 32 | KB: Bel<1,1> Aussie = T ==> Eats(roo) = T 33 | 34 | // She's presumably Italian or a Vegetarian, and 35 | // if she's not Italian, she's probably Australian. 36 | KB: Bel<1,1> truth ==> (Italian = T || Veggie = T) 37 | KB: Bel<1,1> Italian != T ==> Aussie = T 38 | 39 | // Kangaroo is definitely meat, and Vegetarians don't eat meat. 40 | KB: Bel<1,1> Meat(roo) != T ==> falsum 41 | KB: Bel<1,1> ~Fa x ((Veggie == T && Meat(x) == T) -> Eats(x) != T) ==> falsum 42 | 43 | 44 | // The question is now: 45 | // If she's not Italian, is she a Vegetarian? 46 | // We find that out at belief levels 1, 1. 47 | Refute: Bel<0,0> Italian != T ==> Veggie != T 48 | Refute: Bel<0,1> Italian != T ==> Veggie != T 49 | Refute: Bel<1,0> Italian != T ==> Veggie != T 50 | Assert: Bel<1,1> Italian != T ==> Veggie != T 51 | 52 | -------------------------------------------------------------------------------- /examples/tui/test-ws-zoomed-by.limbo: -------------------------------------------------------------------------------- 1 | // Which party is more plausible? 2 | 3 | Sort PARTY 4 | Sort BOOL 5 | 6 | Variable x -> PARTY 7 | 8 | Name partyA -> PARTY 9 | Name partyB -> PARTY 10 | 11 | Name T -> BOOL 12 | 13 | Let false := T /= T 14 | Let true := ~false 15 | 16 | Function zoomed/1 -> BOOL 17 | Function zoom/1 -> BOOL 18 | Function go_fast/1 -> BOOL 19 | Function car/1 -> BOOL 20 | Function going_fast/1 -> BOOL 21 | Function travel_rapidly/1 -> BOOL 22 | Function hurry/1 -> BOOL 23 | KB: G B<1,1> (~zoomed(partyA) == T) ==> (~true) //extracted from WS sentence 24 | KB: G B<1,1> (zoomed(partyA) == T) ==> (zoom(partyA) == T) //zoomed-RelatedTo-> zoom 25 | KB: G B<1,1> (zoom(partyA) == T) ==> (zoomed(partyA) == T) //see above 26 | KB: G B<1,1> (zoomed(partyB) == T) ==> (zoom(partyB) == T) //zoomed-RelatedTo-> zoom 27 | KB: G B<1,1> (zoom(partyB) == T) ==> (zoomed(partyB) == T) //see above 28 | KB: G B<1,1> (zoom(partyA) == T) ==> (travel_rapidly(partyA) == T) //zoom -IsA-> travel_rapidly 29 | KB: G B<1,1> (zoom(partyB) == T) ==> (travel_rapidly(partyB) == T) //zoom -IsA-> travel_rapidly 30 | KB: G B<1,1> (true) ==> (hurry(x) == T -> travel_rapidly(x) == T) //hurry -Synonym-> travel_rapidly 31 | KB: G B<1,1> (true) ==> (travel_rapidly(x) == T -> hurry(x) == T) //hurry -Synonym-> travel_rapidly 32 | KB: G B<1,1> (true) ==> (go_fast(x) == T -> hurry(x) == T) //go_fast -Synonym-> hurry 33 | KB: G B<1,1> (true) ==> (hurry(x) == T -> go_fast(x) == T) //go_fast -Synonym-> hurry 34 | KB: G B<1,1> (go_fast(partyA) == T) ==> (car(partyA) == T) //go_fast -IsA-> car 35 | KB: G B<1,1> (go_fast(partyB) == T) ==> (car(partyB) == T) //go_fast -IsA-> car 36 | KB: G B<1,1> (car(partyA) == T) ==> (going_fast(partyA) == T) //car -UsedFor-> going_fast 37 | KB: G B<1,1> (car(partyB) == T) ==> (going_fast(partyB) == T) //car -UsedFor-> going_fast 38 | KB: G B<1,1> (true) ==> (zoomed(x) == T -> zoom(x) == T) //zoomed -FormOf-> zoom 39 | KB: G B<1,1> (true) ==> (zoom(x) == T -> zoomed(x) == T) //zoomed -FormOf-> zoom 40 | 41 | Assert: G B<1,1> (going_fast(partyA) == T v going_fast(partyB) == T) ==> (going_fast(partyA) == T) 42 | Refute: G B<1,1> (going_fast(partyA) == T v going_fast(partyB) == T) ==> (going_fast(partyB) == T) 43 | 44 | Refute: B<1,1> (going_fast(partyA) == T v going_fast(partyB) == T) ==> (going_fast(partyA) == T) 45 | Assert: B<1,2> (going_fast(partyA) == T v going_fast(partyB) == T) ==> (going_fast(partyA) == T) 46 | Refute: B<1,2> (going_fast(partyA) == T v going_fast(partyB) == T) ==> (going_fast(partyB) == T) 47 | Refute: B<4,4> (going_fast(partyA) == T v going_fast(partyB) == T) ==> (going_fast(partyB) == T) 48 | 49 | Assert: G B<1,1> (going_fast(partyA) == T v going_fast(partyB) == T) ==> (going_fast(partyA) == T) ^ 50 | ~ B<1,1> (going_fast(partyA) == T v going_fast(partyB) == T) ==> (going_fast(partyA) == T) 51 | 52 | -------------------------------------------------------------------------------- /examples/tui/timer.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2014 Christoph Schwering 3 | 4 | #ifndef EXAMPLES_TEXTINTERFACE_TIMER_H_ 5 | #define EXAMPLES_TEXTINTERFACE_TIMER_H_ 6 | 7 | #include 8 | 9 | class Timer { 10 | public: 11 | Timer() : start_(std::clock()) {} 12 | 13 | void start() { 14 | start_ = std::clock() - (end_ != 0 ? end_ - start_ : 0); 15 | ++rounds_; 16 | } 17 | void stop() { end_ = std::clock(); } 18 | void reset() { start_ = 0; end_ = 0; rounds_ = 0; } 19 | 20 | bool started() const { return rounds_ > 0; } 21 | double duration() const { return (end_ - start_) / (double) CLOCKS_PER_SEC; } 22 | size_t rounds() const { return rounds_; } 23 | double avg_duration() const { return duration() / rounds_; } 24 | 25 | private: 26 | std::clock_t start_; 27 | std::clock_t end_ = 0; 28 | size_t rounds_ = 0; 29 | }; 30 | 31 | #endif // EXAMPLES_TEXTINTERFACE_TIMER_H_ 32 | 33 | -------------------------------------------------------------------------------- /examples/upload.sh: -------------------------------------------------------------------------------- 1 | ./zip.sh - | ssh unsw "tar zxvf - -C public_html/limbo/" 2 | 3 | -------------------------------------------------------------------------------- /examples/zip.sh: -------------------------------------------------------------------------------- 1 | OUT=$1 2 | if [ "$1" == "" ] 3 | then 4 | OUT=demo.zip 5 | fi 6 | 7 | if [[ $OUT == *.zip ]] 8 | then 9 | CMD="zip -r $OUT" 10 | elif [[ $OUT == *.tar ]] 11 | then 12 | CMD="tar cvf $OUT" 13 | else 14 | CMD="tar zcf $OUT" 15 | fi 16 | 17 | $CMD \ 18 | index.html jquery*.js \ 19 | minesweeper/minesweeper-js.{html,js,js.mem} minesweeper/*.svg \ 20 | sudoku/sudoku-js.{html,js,js.mem} sudoku/sudokus.txt \ 21 | tui/tui-js.{html,js,js.mem} tui/jquery.terminal*.{js,css} tui/unix_formatting.js tui/*.limbo 22 | 23 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library (limbo INTERFACE) 2 | 3 | target_include_directories (limbo INTERFACE 4 | $ 5 | $ 6 | ) 7 | 8 | -------------------------------------------------------------------------------- /src/limbo/internal/hash.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2016-2017 Christoph Schwering 3 | // Licensed under the MIT license. See LICENSE file in the project root. 4 | // 5 | // Some fast hash functions. 6 | 7 | #ifndef LIMBO_INTERNAL_HASH_H_ 8 | #define LIMBO_INTERNAL_HASH_H_ 9 | 10 | #include 11 | 12 | namespace limbo { 13 | namespace internal { 14 | 15 | typedef u32 hash32_t; 16 | typedef u64 hash64_t; 17 | 18 | hash32_t jenkins_hash(u32 x) { 19 | x = (x + 0x7ed55d16) + (x << 12); 20 | x = (x ^ 0xc761c23c) ^ (x >> 19); 21 | x = (x + 0x165667b1) + (x << 5); 22 | x = (x + 0xd3a2646c) ^ (x << 9); 23 | x = (x + 0xfd7046c5) + (x << 3); 24 | x = (x ^ 0xb55a4f09) ^ (x >> 16); 25 | return x; 26 | } 27 | 28 | template 29 | hash64_t fnv1a_hash(const T& x, hash64_t seed = 0) { 30 | constexpr hash64_t kOffsetBasis = 0xcbf29ce484222325; 31 | constexpr hash64_t kMagicPrime = 0x00000100000001b3; 32 | hash64_t h = seed ^ kOffsetBasis; 33 | for (size_t i = 0; i < sizeof(x); ++i) { 34 | const u8 b = reinterpret_cast(&x)[i]; 35 | h ^= b; 36 | h *= kMagicPrime; 37 | } 38 | return h; 39 | } 40 | 41 | template 42 | u32 MurmurHash2(const T& x, u32 seed ) { 43 | // MurmurHash (32bit hash) by Austin Appleby (public domain). 44 | const u32 m = 0x5bd1e995; 45 | const int r = 24; 46 | u32 h = seed ^ sizeof(x); 47 | 48 | const u64* data = (const u64 *)reinterpret_cast(&x); 49 | size_t len = sizeof(x); 50 | 51 | while (sizeof(x) >= 4) { 52 | u32 k = *(u32*) data; 53 | 54 | k *= m; 55 | k ^= k >> r; 56 | k *= m; 57 | 58 | h *= m; 59 | h ^= k; 60 | 61 | data += 4; 62 | len -= 4; 63 | } 64 | 65 | switch (len) { 66 | case 3: h ^= data[2] << 16; 67 | case 2: h ^= data[1] << 8; 68 | case 1: h ^= data[0]; 69 | h *= m; 70 | } 71 | 72 | h ^= h >> 13; 73 | h *= m; 74 | h ^= h >> 15; 75 | return h; 76 | } 77 | 78 | template 79 | hash64_t murmur64a_hash(const T& x, hash64_t seed = 0) { 80 | // MurmurHash (64bit hash for 64bit CPU) by Austin Appleby (public domain). 81 | const hash64_t m = 0xc6a4a7935bd1e995; 82 | const int r = 47; 83 | 84 | const u64* data = (const u64 *)reinterpret_cast(&x); 85 | const size_t len = sizeof(x); 86 | const u64* end = data + (len / 8); 87 | 88 | hash64_t h = seed ^ (len * m); 89 | 90 | while (data != end) { 91 | u64 k = *data++; 92 | 93 | k *= m; 94 | k ^= k >> r; 95 | k *= m; 96 | 97 | h ^= k; 98 | h *= m; 99 | } 100 | 101 | switch (len & 7) { 102 | case 7: h ^= static_cast(data[6]) << 48; 103 | case 6: h ^= static_cast(data[5]) << 40; 104 | case 5: h ^= static_cast(data[4]) << 32; 105 | case 4: h ^= static_cast(data[3]) << 24; 106 | case 3: h ^= static_cast(data[2]) << 16; 107 | case 2: h ^= static_cast(data[1]) << 8; 108 | case 1: h ^= static_cast(data[0]); 109 | h *= m; 110 | } 111 | 112 | h ^= h >> r; 113 | h *= m; 114 | h ^= h >> r; 115 | return h; 116 | } 117 | 118 | } // namespace internal 119 | } // namespace limbo 120 | 121 | #endif // LIMBO_INTERNAL_HASH_H_ 122 | 123 | -------------------------------------------------------------------------------- /src/limbo/internal/ints.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2017--2019 Christoph Schwering 3 | // Licensed under the MIT license. See LICENSE file in the project root. 4 | // 5 | // Integer utilities. 6 | 7 | #ifndef LIMBO_INTERNAL_INTS_H_ 8 | #define LIMBO_INTERNAL_INTS_H_ 9 | 10 | #include 11 | #include 12 | 13 | namespace limbo { 14 | namespace internal { 15 | 16 | using i8 = std::int8_t; 17 | using i16 = std::int16_t; 18 | using i32 = std::int32_t; 19 | using i64 = std::int64_t; 20 | using u8 = std::uint8_t; 21 | using u16 = std::uint16_t; 22 | using u32 = std::uint32_t; 23 | using u64 = std::uint64_t; 24 | using uint = unsigned int; 25 | using size_t = std::size_t; 26 | using uptr_t = std::uintptr_t; 27 | using iptr_t = std::intptr_t; 28 | 29 | template 30 | struct BitInterleaver {}; 31 | 32 | template 33 | struct BitInterleaver { 34 | static constexpr u32 kHi = 0xAAAAAAAA; 35 | static constexpr u32 kLo = 0x55555555; 36 | static u32 merge(u16 hi, u16 lo) { return _pdep_u32(hi, kHi) | _pdep_u32(lo, kLo); } 37 | static u16 split_hi(u32 z) { return _pext_u32(z, kHi); } 38 | static u16 split_lo(u32 z) { return _pext_u32(z, kLo); } 39 | }; 40 | 41 | template 42 | struct BitInterleaver { 43 | static constexpr u64 kHi = 0xAAAAAAAAAAAAAAAA; 44 | static constexpr u64 kLo = 0x5555555555555555; 45 | static u64 merge(u32 hi, u32 lo) { return _pdep_u64(hi, kHi) | _pdep_u64(lo, kLo); } 46 | static u32 split_hi(u64 z) { return _pext_u64(z, kHi); } 47 | static u32 split_lo(u64 z) { return _pext_u64(z, kLo); } 48 | }; 49 | 50 | template 51 | struct BitConcatenator {}; 52 | 53 | template 54 | struct BitConcatenator { 55 | static constexpr u32 kLo = ~u16(0); 56 | static constexpr u32 kHi = ~kLo; 57 | static u32 merge(u16 hi, u16 lo) { return (u32(hi) << 16) | u32(lo); } 58 | static u16 split_hi(u32 z) { return u16(z >> 16); } 59 | static u16 split_lo(u32 z) { return u16(z); } 60 | }; 61 | 62 | template 63 | struct BitConcatenator { 64 | static constexpr u64 kLo = ~u32(0); 65 | static constexpr u64 kHi = ~kLo; 66 | static u64 merge(u32 hi, u32 lo) { return (u64(hi) << 32) | u64(lo); } 67 | static u32 split_hi(u64 z) { return u32(z >> 32); } 68 | static u32 split_lo(u64 z) { return u32(z); } 69 | }; 70 | 71 | ulong next_power_of_two(ulong n) { 72 | n += !n; 73 | return static_cast(1) << (sizeof(ulong) * 8 - 1 - __builtin_clzl(n+n-1)); 74 | } 75 | 76 | } // namespace internal 77 | } // namespace limbo 78 | 79 | #endif // LIMBO_INTERNAL_INTS_H_ 80 | 81 | -------------------------------------------------------------------------------- /src/limbo/internal/maybe.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2014-2016 Christoph Schwering 3 | // Licensed under the MIT license. See LICENSE file in the project root. 4 | // 5 | // A simple Maybe type as in Haskell: it is either Nothing or Just some object. 6 | // Thanks to moving constructors and all that weird stuff, it's faster than 7 | // using pairs with a boolean for the same purpose -- let alone much clearer. 8 | // 9 | // To handle Maybe> we use std::forward(). Is that correct? 10 | 11 | #ifndef LIMBO_INTERNAL_MAYBE_H_ 12 | #define LIMBO_INTERNAL_MAYBE_H_ 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | namespace limbo { 20 | namespace internal { 21 | 22 | template 23 | struct Maybe { 24 | Maybe() = default; 25 | explicit Maybe(T&& val) : val(std::forward(val)), yes(true) {} 26 | explicit Maybe(bool yes, T&& val) : val(std::forward(val)), yes(yes) {} 27 | ~Maybe() = default; 28 | 29 | Maybe(const Maybe&) = default; 30 | Maybe& operator=(const Maybe&) = default; 31 | template 32 | Maybe(const Maybe& m) : val(m.val), yes(m.yes) {} 33 | 34 | Maybe(Maybe&&) = default; 35 | Maybe& operator=(Maybe&&) = default; 36 | template 37 | Maybe(Maybe&& m) : val(std::forward(m.val)), yes(m.yes) {} 38 | 39 | bool operator==(const Maybe& m) const { return yes == m.yes && (!yes || val == m.val); } 40 | bool operator!=(const Maybe& m) const { return !(*this == m); } 41 | 42 | template bool operator==(const Maybe& m) const { return yes == m.yes && (!yes || val == m.val); } 43 | template bool operator!=(const Maybe& m) const { return !(*this == m); } 44 | 45 | explicit operator bool() const { return yes; } 46 | 47 | T val{}; 48 | bool yes = false; 49 | }; 50 | 51 | constexpr struct { 52 | template 53 | operator Maybe() const { return Maybe(); } 54 | } Nothing{}; 55 | 56 | template 57 | Maybe::type>::type> Just(T&& val) { // NOLINT 58 | return Maybe(std::forward(val)); // NOLINT 59 | } 60 | 61 | } // namespace internal 62 | } // namespace limbo 63 | 64 | #endif // LIMBO_INTERNAL_MAYBE_H_ 65 | 66 | -------------------------------------------------------------------------------- /src/limbo/internal/ringbuffer.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2019 Christoph Schwering 3 | // Licensed under the MIT license. See LICENSE file in the project root. 4 | // 5 | // RingBuffer that grows on demand. 6 | 7 | #ifndef LIMBO_INTERNAL_RINGBUFFER_H_ 8 | #define LIMBO_INTERNAL_RINGBUFFER_H_ 9 | 10 | #include 11 | #include 12 | 13 | template 14 | class RingBuffer { 15 | public: 16 | RingBuffer() = default; 17 | 18 | RingBuffer(const RingBuffer&) = delete; 19 | RingBuffer& operator=(const RingBuffer&) = delete; 20 | 21 | RingBuffer(RingBuffer&& b) 22 | : xs_(b.xs_), 23 | capacity_(b.capacity_), 24 | begin_(b.begin_), 25 | end_(b.end_) { 26 | b.xs_ = nullptr; 27 | b.capacity_ = 0; 28 | b.begin_ = 0; 29 | b.end_ = 0; 30 | } 31 | RingBuffer& operator=(RingBuffer&& b) { 32 | if (this != &b) { 33 | delete xs_; 34 | xs_ = b.xs_; 35 | capacity_ = b.capacity_; 36 | begin_ = b.begin_; 37 | end_ = b.end_; 38 | b.xs_ = nullptr; 39 | b.capacity_ = 0; 40 | b.begin_ = 0; 41 | b.end_ = 0; 42 | } 43 | return *this; 44 | } 45 | 46 | ~RingBuffer() { delete[] xs_; } 47 | 48 | int size() const { return begin_ <= end_ ? end_ - begin_ : capacity_ - begin_ + end_; } 49 | bool empty() const { return begin_ == end_; } 50 | 51 | T& operator[](int i) { return xs_[(begin_ + i) % capacity_]; } 52 | const T& operator[](int i) const { return xs_[(begin_ + i) % capacity_]; } 53 | 54 | void PushFront(T&& x) { 55 | if (full()) { 56 | Grow(); 57 | } 58 | assert(!full()); 59 | begin_ = pred(begin_); 60 | xs_[begin_] = std::move(x); 61 | } 62 | 63 | void PushFront(const T& x) { 64 | if (full()) { 65 | Grow(); 66 | } 67 | assert(!full()); 68 | begin_ = pred(begin_); 69 | xs_[begin_] = x; 70 | } 71 | 72 | T PopFront() { 73 | assert(!empty()); 74 | T x = std::move(xs_[begin_]); 75 | begin_ = succ(begin_); 76 | return x; 77 | } 78 | 79 | void PushBack(T&& x) { 80 | if (full()) { 81 | Grow(); 82 | } 83 | assert(!full()); 84 | xs_[end_] = std::move(x); 85 | end_ = succ(end_); 86 | } 87 | 88 | void PushBack(const T& x) { 89 | if (full()) { 90 | Grow(); 91 | } 92 | assert(!full()); 93 | xs_[end_] = x; 94 | end_ = succ(end_); 95 | } 96 | 97 | T PopBack() { 98 | assert(!empty()); 99 | end_ = pred(end_); 100 | T x = std::move(xs_[end_]); 101 | return x; 102 | } 103 | 104 | private: 105 | bool full() const { return xs_ == nullptr || size() == capacity_ - 1; } 106 | 107 | int succ(int i) const { return (i + 1) % capacity_; } 108 | int pred(int i) const { return ((i - 1) + capacity_) % capacity_; } 109 | 110 | void Grow() { 111 | const int new_capacity = capacity_ * 3 / 2 + 2; 112 | T* xs = new T[new_capacity]; 113 | const int s = size(); 114 | for (int i = 0; i < s; ++i) { 115 | xs[i] = std::move((*this)[i]); 116 | } 117 | delete[] xs_; 118 | xs_ = xs; 119 | capacity_ = new_capacity; 120 | begin_ = 0; 121 | end_ = s; 122 | } 123 | 124 | T* xs_ = nullptr; 125 | int capacity_ = 0; 126 | int begin_ = 0; // inclusive 127 | int end_ = 0; // exclusive 128 | }; 129 | 130 | #endif // LIMBO_INTERNAL_RINGBUFFER_H_ 131 | 132 | -------------------------------------------------------------------------------- /src/limbo/internal/singleton.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2017--2018 Christoph Schwering 3 | // Licensed under the MIT license. See LICENSE file in the project root. 4 | // 5 | // Singleton base class. 6 | 7 | #ifndef LIMBO_INTERNAL_SINGLETON_H_ 8 | #define LIMBO_INTERNAL_SINGLETON_H_ 9 | 10 | #include 11 | 12 | namespace limbo { 13 | namespace internal { 14 | 15 | template 16 | struct Singleton { 17 | static std::unique_ptr instance_; 18 | }; 19 | 20 | template 21 | std::unique_ptr Singleton::instance_ = nullptr; 22 | 23 | } // namespace internal 24 | } // namespace limbo 25 | 26 | #endif // LIMBO_INTERNAL_SINGLETON_H_ 27 | 28 | -------------------------------------------------------------------------------- /src/limbo/internal/subsets.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2019 Christoph Schwering 3 | // Licensed under the MIT license. See LICENSE file in the project root. 4 | // 5 | // Functions to determine all subsets. 6 | 7 | #ifndef LIMBO_INTERNAL_SUBSETS_H_ 8 | #define LIMBO_INTERNAL_SUBSETS_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace limbo { 16 | namespace internal { 17 | 18 | template 22 | bool AllSubsetsOfSize(RandomAccessIt X_begin, 23 | RandomAccessIt X_end, 24 | const int xs_wanted, 25 | SetContainer* xs, 26 | UnaryPredicate pred = UnaryPredicate()) { 27 | int X_size = int(std::distance(X_begin, X_end)); 28 | if (xs_wanted == 0 || X_size == 0) { 29 | return xs_wanted == 0 && pred(xs); 30 | } else if (X_size < xs_wanted) { 31 | return false; 32 | } else { 33 | if (X_size > xs_wanted) { 34 | const bool succ = AllSubsetsOfSize(std::next(X_begin), X_end, xs_wanted, xs, pred); 35 | if (!succ) { 36 | return false; 37 | } 38 | } 39 | const T& x = *X_begin; 40 | xs->push_back(x); 41 | const bool succ = AllSubsetsOfSize(std::next(X_begin), X_end, xs_wanted - 1, xs, pred); 42 | xs->pop_back(); 43 | return succ; 44 | } 45 | } 46 | 47 | template 51 | bool AllCombinedSubsetsOfSize(const SetSetContainer& Xs, 52 | const std::vector& n_not_yet_covered_in, 53 | const int xs_wanted, 54 | const int index, 55 | std::vector* xs, 56 | UnaryPredicate pred = UnaryPredicate()) { 57 | assert(index <= int(Xs.size())); 58 | if (index == int(Xs.size())) { 59 | return Xs.empty() || (xs_wanted == 0 && pred(*xs)); 60 | } 61 | assert(!Xs[index].empty()); 62 | // What is the minimum number of functions we xs_wanted to assign from this bucket? 63 | // (xs_wanted - min_assign < n_not_yet_covered_in[index] - (n_not_yet_covered_in.size() - index - 1)) 64 | // <=> (min_assign > xs_wanted - n_not_yet_covered_in[index] + n_not_yet_covered_in.size() - index - 1) 65 | // <=> (min_assign >= xs_wanted - n_not_yet_covered_in[index] + n_not_yet_covered_in.size() - index - 1) 66 | const int min_assign = std::max(0, 67 | xs_wanted - n_not_yet_covered_in[index] + int(n_not_yet_covered_in.size()) - index - 1); 68 | // What is the maximum number of functions we can assign from this buckt? 69 | const int max_assign = std::min(xs_wanted - xs->empty(), int(Xs[index].size()) - 1); 70 | for (int i = min_assign; i <= max_assign; ++i) { 71 | const bool succ = AllSubsetsOfSize(Xs[index].begin(), Xs[index].end(), i, xs, [&](std::vector* xs) { 72 | bool succ = AllCombinedSubsetsOfSize(Xs, n_not_yet_covered_in, xs_wanted - i, index + 1, xs, pred); 73 | return succ; 74 | }); 75 | if (!succ) { 76 | return false; 77 | } 78 | } 79 | //std::printf("%d: true\n", __LINE__); 80 | return true; 81 | } 82 | 83 | template 87 | bool AllCombinedSubsetsOfSize(const SetSetContainer& Xs, const int xs_wanted, UnaryPredicate pred = UnaryPredicate()) { 88 | SetContainer xs; 89 | std::vector n_not_yet_covered_in(Xs.size()); 90 | for (int i = int(n_not_yet_covered_in.size()) - 2; i >= 0; --i) { 91 | n_not_yet_covered_in[i] = int(Xs[i+1].size()) + n_not_yet_covered_in[i+1]; 92 | } 93 | //for (int i = 0; i < Xs.size(); ++i) { printf("Xs[%d] =", i); for (const T f : Xs[i]) { printf(" %d", int(f)); } printf("\n"); } 94 | //for (int i = 0; i < Xs.size(); ++i) { printf("n_not_yet_covered_in[%d] = %d\n", i, n_not_yet_covered_in[i]); } printf("\n"); 95 | return AllCombinedSubsetsOfSize(Xs, n_not_yet_covered_in, xs_wanted, 0, &xs, pred); 96 | } 97 | 98 | } // namespace internal 99 | } // namespace limbo 100 | 101 | #endif // LIMBO_INTERNAL_SUBSETS_H_ 102 | 103 | -------------------------------------------------------------------------------- /src/limbo/io/input.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2019 Christoph Schwering 3 | // Licensed under the MIT license. See LICENSE file in the project root. 4 | 5 | #ifndef LIMBO_IO_INPUT_H_ 6 | #define LIMBO_IO_INPUT_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace limbo { 15 | namespace io { 16 | 17 | // istreambuf_iterators are InputIterators, but our lexer wants a 18 | // ForwardIterator, so we need to wrap it. 19 | template> 20 | class MultiPassIterator { 21 | public: 22 | using difference_type = typename InputIt::difference_type; 23 | using value_type = typename InputIt::value_type; 24 | using reference = value_type; 25 | using pointer = value_type*; 26 | using iterator_category = std::forward_iterator_tag; 27 | 28 | struct Proxy { 29 | public: 30 | using value_type = typename InputIt::value_type; 31 | using reference = typename InputIt::reference; 32 | using pointer = typename InputIt::pointer; 33 | 34 | reference operator*() const { return v; } 35 | pointer operator->() const { return &v; } 36 | 37 | mutable typename std::remove_const::type v; 38 | }; 39 | 40 | 41 | MultiPassIterator() = default; 42 | MultiPassIterator(InputIt it) : data_(new Data(it)) {} 43 | 44 | bool operator==(const MultiPassIterator it) const { 45 | return (data_ == it.data_ && index_ == it.index_) || (dead() && it.dead()); 46 | } 47 | bool operator!=(const MultiPassIterator it) const { return !(*this == it); } 48 | 49 | reference operator*() const { 50 | buffer_until_index(); 51 | return data_->buf_[index_]; 52 | } 53 | 54 | MultiPassIterator& operator++() { 55 | // When our index has reached the end, we also need to advance the input 56 | // iterator. Otherwise we wouldn't detect when we have reached the end 57 | // input iterator. 58 | buffer_until_index(); 59 | ++index_; 60 | return *this; 61 | } 62 | 63 | Proxy operator->() const { return Proxy{operator*()}; } 64 | Proxy operator++(int) const { Proxy p{operator*()}; operator++(); return p; } 65 | 66 | private: 67 | struct Data { 68 | explicit Data(InputIt it) : it_(it) {} 69 | InputIt it_; 70 | Buffer buf_; 71 | }; 72 | 73 | bool buffered() const { return index_ < data_->buf_.size(); } 74 | bool dead() const { return !data_ || (data_->it_ == InputIt() && !buffered()); } 75 | 76 | void buffer_until_index() const { 77 | for (; !buffered(); ++(data_->it_)) { 78 | data_->buf_.push_back(*data_->it_); 79 | } 80 | } 81 | 82 | std::shared_ptr data_; 83 | size_t index_ = 0; 84 | }; 85 | 86 | std::istream& operator>>(std::istream& is, Formula& f) { 87 | using StreamIterator = MultiPassIterator>; 88 | using Parser = Parser; 89 | Parser parser = Parser(StreamIterator(is), StreamIterator()); 90 | parser.set_default_if_undeclared(true); 91 | Parser::Result> parse_result = parser.ParseFormula(); 92 | if (!parse_result) { 93 | is.setstate(std::ios::failbit); 94 | return is; 95 | } 96 | Parser::Result computation_result = parse_result.val.Compute(); 97 | if (!computation_result) { 98 | is.setstate(std::ios::failbit); 99 | return is; 100 | } 101 | f = std::move(computation_result.val); 102 | return is; 103 | } 104 | 105 | } // namespace io 106 | } // namespace limbo 107 | 108 | using limbo::io::operator>>; // I too often forget this, so for now, it's here 109 | 110 | #endif // LIMBO_IO_INPUT_H_ 111 | 112 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory (googletest) 2 | enable_testing () 3 | include_directories (${gtest_SOURCE_DIR}/include ${gmock_SOURCE_DIR}/include) 4 | 5 | foreach (test dense hash ints ringbuffer singleton subsets lit clause formula sat limsat) 6 | add_executable (${test}-test ${test}.cc) 7 | target_link_libraries (${test}-test LINK_PUBLIC limbo gtest gtest_main gmock) 8 | add_test (NAME ${test} COMMAND ${test}-test) 9 | endforeach () 10 | 11 | -------------------------------------------------------------------------------- /tests/clause.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2014 Christoph Schwering 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace limbo { 10 | 11 | TEST(ClauseTest, Normalize) { 12 | Fun f = Fun::FromId(1); 13 | Fun g = Fun::FromId(2); 14 | Name m = Name::FromId(1); 15 | Name n = Name::FromId(2); 16 | 17 | { 18 | Lit as[] = {Lit::Eq(f, n), Lit::Eq(f, n), Lit::Neq(f, m), Lit::Neq(g, n), Lit::Neq(g, n), Lit::Eq(g, m), Lit::Eq(g, m)}; 19 | const size_t len = Clause::Normalize(sizeof(as) / sizeof(as[0]), as, Clause::InvalidityPromise{false}); 20 | EXPECT_EQ(len, 2); 21 | EXPECT_EQ(as[0], Lit::Neq(f, m)); 22 | EXPECT_EQ(as[1], Lit::Neq(g, n)); 23 | } 24 | 25 | { 26 | Lit as[] = {Lit::Eq(f, n), Lit::Eq(f, n), Lit::Neq(f, m), Lit::Neq(g, n), Lit::Neq(g, n), Lit::Eq(g, m), Lit::Eq(g, m), Lit::Neq(g, m)}; 27 | const size_t len = Clause::Normalize(sizeof(as) / sizeof(as[0]), as, Clause::InvalidityPromise{true}); 28 | EXPECT_EQ(len, 3); 29 | EXPECT_EQ(as[0], Lit::Neq(f, m)); 30 | EXPECT_EQ(as[1], Lit::Neq(g, n)); 31 | EXPECT_EQ(as[2], Lit::Neq(g, m)); 32 | } 33 | 34 | { 35 | Lit as[] = {Lit::Eq(f, n), Lit::Eq(f, n), Lit::Neq(f, m), Lit::Neq(g, n), Lit::Neq(g, n), Lit::Eq(g, m), Lit::Eq(g, m), Lit::Neq(g, m)}; 36 | const size_t len = Clause::Normalize(sizeof(as) / sizeof(as[0]), as, Clause::InvalidityPromise{false}); 37 | EXPECT_EQ(len, -1); 38 | } 39 | } 40 | 41 | TEST(ClauseTest, ClauseFactory) { 42 | Fun f = Fun::FromId(1); 43 | Fun g = Fun::FromId(2); 44 | Name m = Name::FromId(1); 45 | Name n = Name::FromId(2); 46 | Clause::Factory factory; 47 | 48 | { 49 | Clause::Factory::CRef cr = factory.New({Lit::Eq(f, n), Lit::Eq(f, n), Lit::Neq(f, m), Lit::Neq(g, n), Lit::Neq(g, n), Lit::Eq(g, m), Lit::Eq(g, m)}); 50 | EXPECT_NE(cr, Clause::Factory::CRef::kNull); 51 | EXPECT_NE(cr, Clause::Factory::CRef::kDomain); 52 | Clause& c = factory[cr]; 53 | EXPECT_FALSE(c.valid()); 54 | EXPECT_EQ(c.size(), 2); 55 | EXPECT_EQ(c[0], Lit::Neq(f, m)); 56 | EXPECT_EQ(c[1], Lit::Neq(g, n)); 57 | EXPECT_THAT(c, ::testing::ElementsAre(Lit::Neq(f, m), Lit::Neq(g, n))); 58 | EXPECT_FALSE(c.unit()); 59 | EXPECT_FALSE(c.learnt()); 60 | 61 | Clause::Factory::CRef cr2 = factory.New({Lit::Neq(f, m), Lit::Neq(g, n)}); 62 | EXPECT_NE(cr, cr2); 63 | const Clause& d = factory[cr2]; 64 | EXPECT_EQ(c, d); 65 | EXPECT_FALSE(d.valid()); 66 | EXPECT_FALSE(d.unit()); 67 | EXPECT_FALSE(d.learnt()); 68 | EXPECT_TRUE(c.Subsumes(d)); 69 | EXPECT_TRUE(d.Subsumes(c)); 70 | 71 | Clause::Factory::CRef cr3 = factory.New({Lit::Eq(f, n)}); 72 | const Clause& u = factory[cr3]; 73 | EXPECT_NE(c, u); 74 | EXPECT_TRUE(u.unit()); 75 | EXPECT_EQ(u[0], Lit::Eq(f, n)); 76 | EXPECT_THAT(u, ::testing::ElementsAre(Lit::Eq(f, n))); 77 | EXPECT_FALSE(u.valid()); 78 | EXPECT_FALSE(c.Subsumes(u)); 79 | EXPECT_TRUE(u.Subsumes(c)); 80 | 81 | const int removed = c.RemoveIf([g](const Lit a) { return a.fun() == g; }); 82 | EXPECT_EQ(removed, 1); 83 | EXPECT_NE(c, d); 84 | EXPECT_FALSE(c.valid()); 85 | EXPECT_EQ(c.size(), 1); 86 | EXPECT_EQ(c[0], Lit::Neq(f, m)); 87 | EXPECT_THAT(c, ::testing::ElementsAre(Lit::Neq(f, m))); 88 | EXPECT_TRUE(c.unit()); 89 | EXPECT_FALSE(c.learnt()); 90 | } 91 | 92 | { 93 | Clause::Factory::CRef cr = factory.New({Lit::Eq(f, n), Lit::Eq(f, n), Lit::Neq(f, m), Lit::Neq(g, n), Lit::Neq(g, n), Lit::Eq(g, m), Lit::Eq(g, m), Lit::Neq(g, m)}); 94 | EXPECT_NE(cr, Clause::Factory::CRef::kNull); 95 | EXPECT_NE(cr, Clause::Factory::CRef::kDomain); 96 | const Clause& c = factory[cr]; 97 | EXPECT_TRUE(c.valid()); 98 | EXPECT_EQ(c.size(), 1); 99 | EXPECT_TRUE(c.unit()); 100 | EXPECT_FALSE(c.learnt()); 101 | EXPECT_TRUE(c[0].null()); 102 | } 103 | } 104 | 105 | } // namespace limbo 106 | 107 | -------------------------------------------------------------------------------- /tests/dense.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2016 Christoph Schwering 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace limbo { 9 | namespace internal { 10 | 11 | template 12 | size_t length(T r) { return std::distance(r.begin(), r.end()); } 13 | 14 | template 15 | struct To { Target operator()(Source x) const { return Target(x); } }; 16 | 17 | template 18 | using IntMap = DenseMap, To, SlowAdjustBoundCheck>; 19 | 20 | TEST(DenseMapTest, general) { 21 | IntMap map; 22 | map[0] = "zero"; 23 | map[2] = "two"; 24 | EXPECT_EQ(map[0], "zero"); 25 | EXPECT_EQ(map[1], ""); 26 | EXPECT_EQ(map[2], "two"); 27 | EXPECT_EQ(length(map.keys()), 3u); 28 | EXPECT_EQ(length(map.values()), 3u); 29 | EXPECT_EQ(map.upper_bound_key(), 2); 30 | EXPECT_EQ(map.upper_bound_index(), 2); 31 | 32 | const IntMap map2 = map; 33 | EXPECT_EQ(length(map2.keys()), 3u); 34 | EXPECT_EQ(length(map2.values()), 3u); 35 | EXPECT_EQ(map2[0], "zero"); 36 | EXPECT_EQ(map2[1], ""); 37 | EXPECT_EQ(map2[2], "two"); 38 | 39 | map[1] = "one"; 40 | EXPECT_EQ(map[0], "zero"); 41 | EXPECT_EQ(map[1], "one"); 42 | EXPECT_EQ(map[2], "two"); 43 | 44 | EXPECT_EQ(map2[0], "zero"); 45 | EXPECT_EQ(map2[1], ""); 46 | EXPECT_EQ(map2[2], "two"); 47 | 48 | //map.set_null_value("null"); 49 | map[4] = "four"; 50 | EXPECT_EQ(length(map.keys()), 5u); 51 | EXPECT_EQ(length(map.values()), 5u); 52 | EXPECT_EQ(map.upper_bound_key(), 4); 53 | EXPECT_EQ(map.upper_bound_index(), 4); 54 | EXPECT_EQ(map[0], "zero"); 55 | EXPECT_EQ(map[1], "one"); 56 | EXPECT_EQ(map[2], "two"); 57 | EXPECT_EQ(map[3], ""); 58 | EXPECT_EQ(map[4], "four"); 59 | } 60 | 61 | } // namespace internal 62 | } // namespace limbo 63 | 64 | -------------------------------------------------------------------------------- /tests/hash.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2016 Christoph Schwering 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | namespace limbo { 11 | namespace internal { 12 | 13 | TEST(HashTest, hash) { 14 | std::vector ints1; 15 | std::vector ints2; 16 | for (uint64_t i = 0, n = 1; i <= 19; ++i, n *= 10UL) { 17 | ASSERT_LE(0UL + n, UINT64_MAX); 18 | ASSERT_LE(1UL + n, UINT64_MAX); 19 | ints1.push_back(0UL + n); 20 | ints2.push_back(1UL + n); 21 | } 22 | for (uint64_t i1 : ints1) { 23 | uint64_t copy = i1; 24 | EXPECT_EQ(i1, copy); 25 | EXPECT_EQ(fnv1a_hash(i1), fnv1a_hash(copy)); 26 | for (uint64_t i2 : ints2) { 27 | EXPECT_NE(i1, i2); 28 | EXPECT_NE(fnv1a_hash(i1), fnv1a_hash(i2)); 29 | } 30 | } 31 | } 32 | 33 | } // namespace internal 34 | } // namespace limbo 35 | 36 | -------------------------------------------------------------------------------- /tests/ints.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2016 Christoph Schwering 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | namespace limbo { 11 | namespace internal { 12 | 13 | TEST(IntsTest, ints) { 14 | EXPECT_EQ(sizeof(i8 ), 1u); 15 | EXPECT_EQ(sizeof(i16 ), 2u); 16 | EXPECT_EQ(sizeof(i32 ), 4u); 17 | EXPECT_EQ(sizeof(i64 ), 8u); 18 | EXPECT_EQ(sizeof(u8 ), 1u); 19 | EXPECT_EQ(sizeof(u16 ), 2u); 20 | EXPECT_EQ(sizeof(u32 ), 4u); 21 | EXPECT_EQ(sizeof(u64 ), 8u); 22 | EXPECT_EQ(sizeof(uint), sizeof(int)); 23 | EXPECT_EQ(sizeof(size_t), 8); 24 | EXPECT_EQ(sizeof(uptr_t), sizeof(void*)); 25 | EXPECT_EQ(sizeof(iptr_t), sizeof(void*)); 26 | } 27 | 28 | TEST(IntsTest, BitInterleaver) { 29 | EXPECT_EQ(BitInterleaver::merge(0b100100, 0b000000), 0b100000100000); 30 | EXPECT_EQ(BitInterleaver::merge(0b000000, 0b100100), 0b010000010000); 31 | EXPECT_EQ(BitInterleaver::merge(0b000101, 0b000011), 0b000000100111); 32 | EXPECT_EQ(BitInterleaver::merge(0b100100, 0b000000), 0b100000100000L); 33 | EXPECT_EQ(BitInterleaver::merge(0b000000, 0b100100), 0b010000010000L); 34 | EXPECT_EQ(BitInterleaver::merge(0b000101, 0b000011), 0b000000100111L); 35 | } 36 | 37 | TEST(IntsTest, BitConcatenator) { 38 | EXPECT_EQ(BitConcatenator::merge(0b100100, 0b000000), 0b100100 << 16); 39 | EXPECT_EQ(BitConcatenator::merge(0b000000, 0b100100), 0b100100); 40 | EXPECT_EQ(BitConcatenator::merge(0b000101, 0b000011), (0b000101 << 16) | 0b000011); 41 | EXPECT_EQ(BitConcatenator::merge(0b100100, 0b000000), 0b100100L << 32); 42 | EXPECT_EQ(BitConcatenator::merge(0b000000, 0b100100), 0b100100L); 43 | EXPECT_EQ(BitConcatenator::merge(0b000101, 0b000011), (0b000101L << 32) | 0b000011L); 44 | } 45 | 46 | TEST(IntsTest, next_power_of_two) { 47 | EXPECT_EQ(next_power_of_two(128), 128); 48 | EXPECT_EQ(next_power_of_two(127), 128); 49 | EXPECT_EQ(next_power_of_two(111), 128); 50 | EXPECT_EQ(next_power_of_two(47), 64); 51 | } 52 | 53 | } // namespace internal 54 | } // namespace limbo 55 | 56 | -------------------------------------------------------------------------------- /tests/limsat.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2014 Christoph Schwering 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace limbo { 9 | 10 | TEST(LimSatTest, LimSat) { 11 | } 12 | 13 | 14 | } // namespace limbo 15 | 16 | -------------------------------------------------------------------------------- /tests/ringbuffer.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2016 Christoph Schwering 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | namespace limbo { 11 | namespace internal { 12 | 13 | TEST(RingBufferTest, EmptyRingBuffer) { 14 | RingBuffer rb; 15 | EXPECT_EQ(rb.size(), 0); 16 | } 17 | 18 | TEST(RingBufferTest, RingBufferFrontAndBack) { 19 | RingBuffer rb; 20 | for (int i = 0; i < 1000; ++i) { 21 | rb.PushFront(-i - 1); 22 | rb.PushBack(i); 23 | } 24 | EXPECT_EQ(rb.size(), 2000); 25 | for (int i = 0; i < rb.size(); ++i) { 26 | EXPECT_EQ(rb[i], i - 1000); 27 | } 28 | 29 | { 30 | RingBuffer tmp(std::move(rb)); 31 | EXPECT_TRUE(rb.empty()); 32 | EXPECT_EQ(rb.size(), 0); 33 | EXPECT_FALSE(tmp.empty()); 34 | EXPECT_EQ(tmp.size(), 2000); 35 | for (int i = 0; i < tmp.size(); ++i) { 36 | EXPECT_EQ(tmp[i], i - 1000); 37 | } 38 | rb = std::move(tmp); 39 | } 40 | 41 | for (int i = 999; i >= 0; --i) { 42 | int x = rb.PopBack(); 43 | EXPECT_EQ(x, i); 44 | } 45 | EXPECT_EQ(rb.size(), 1000); 46 | for (int i = 0; i < rb.size(); ++i) { 47 | EXPECT_EQ(rb[i], i - 1000); 48 | } 49 | for (int i = -1; i >= 1000; --i) { 50 | int x = rb.PopBack(); 51 | EXPECT_EQ(x, i); 52 | } 53 | } 54 | 55 | } // namespace internal 56 | } // namespace limbo 57 | 58 | -------------------------------------------------------------------------------- /tests/sat.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2014 Christoph Schwering 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace limbo { 9 | 10 | TEST(SatTest, sat) { 11 | } 12 | 13 | 14 | } // namespace limbo 15 | 16 | -------------------------------------------------------------------------------- /tests/singleton.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2016 Christoph Schwering 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | namespace limbo { 11 | namespace internal { 12 | 13 | int instances = 0; 14 | 15 | class Thing : private Singleton { 16 | public: 17 | static Thing& instance() { 18 | if (instance_ == nullptr) { 19 | instance_ = std::unique_ptr(new Thing()); 20 | } 21 | return *instance_.get(); 22 | } 23 | 24 | private: 25 | Thing() { ++instances; } 26 | }; 27 | 28 | TEST(SingletonTest, NumberOfInstances) { 29 | ASSERT_EQ(instances, 0); 30 | Thing::instance(); 31 | EXPECT_EQ(instances, 1); 32 | Thing::instance(); 33 | EXPECT_EQ(instances, 1); 34 | } 35 | 36 | } // namespace internal 37 | } // namespace limbo 38 | 39 | -------------------------------------------------------------------------------- /tests/subsets.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2019 Christoph Schwering 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace limbo { 13 | namespace internal { 14 | 15 | TEST(SubsetsTest, subsets_empty_set_cardinality_zero) { 16 | std::vector> Xs; 17 | std::set> Ys; 18 | int n_subsets = 0; 19 | bool r = AllCombinedSubsetsOfSize(Xs, 0, [&](const std::vector& xs) { std::cout << xs << std::endl; Ys.insert(xs); ++n_subsets; return true; }); 20 | EXPECT_TRUE(r); 21 | EXPECT_EQ(n_subsets, 0); 22 | r = AllCombinedSubsetsOfSize(Xs, 0, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return false; }); 23 | EXPECT_TRUE(r); 24 | } 25 | 26 | TEST(SubsetsTest, subsets_empty_set_cardinality_one) { 27 | std::vector> Xs; 28 | std::set> Ys; 29 | int n_subsets = 0; 30 | bool r = AllCombinedSubsetsOfSize(Xs, 1, [&](const std::vector& xs) { std::cout << xs << std::endl; Ys.insert(xs); ++n_subsets; return true; }); 31 | EXPECT_TRUE(r); 32 | EXPECT_EQ(n_subsets, 0); 33 | r = AllCombinedSubsetsOfSize(Xs, 0, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return false; }); 34 | EXPECT_TRUE(r); 35 | } 36 | 37 | TEST(SubsetsTest, subsets_two_ternary_sets_cardinality_zero) { 38 | std::vector> Xs; 39 | Xs.push_back({1, 2, 3}); 40 | Xs.push_back({11, 22, 33}); 41 | std::set> Ys; 42 | unsigned int n_subsets = 0; 43 | bool r = AllCombinedSubsetsOfSize(Xs, 0, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return true; }); 44 | EXPECT_TRUE(r); 45 | EXPECT_EQ(n_subsets, 0); 46 | r = AllCombinedSubsetsOfSize(Xs, 0, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return false; }); 47 | EXPECT_TRUE(r); 48 | } 49 | 50 | TEST(SubsetsTest, subsets_two_ternary_sets_cardinality_one) { 51 | std::vector> Xs; 52 | Xs.push_back({1, 2, 3}); 53 | Xs.push_back({11, 22, 33}); 54 | std::set> Ys; 55 | unsigned int n_subsets = 0; 56 | bool r = AllCombinedSubsetsOfSize(Xs, 1, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return true; }); 57 | EXPECT_TRUE(r); 58 | EXPECT_EQ(n_subsets, 0); 59 | r = AllCombinedSubsetsOfSize(Xs, 1, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return false; }); 60 | EXPECT_TRUE(r); 61 | } 62 | 63 | TEST(SubsetsTest, subsets_two_ternary_sets_cardinality_two) { 64 | std::vector> Xs; 65 | Xs.push_back({1, 2, 3}); 66 | Xs.push_back({11, 22, 33}); 67 | std::set> Ys; 68 | int n_subsets = 0; 69 | bool r = AllCombinedSubsetsOfSize(Xs, 2, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return true; }); 70 | EXPECT_TRUE(r); 71 | EXPECT_EQ(n_subsets, 3*3); 72 | for (int i = 1; i <= 3; ++i) { 73 | for (int j = 11; j <= 33; j += 11) { 74 | EXPECT_TRUE(Ys.find({i,j}) != Ys.end()); 75 | } 76 | } 77 | } 78 | 79 | TEST(SubsetsTest, subsets_two_ternary_sets_cardinality_three) { 80 | std::vector> Xs; 81 | Xs.push_back({1, 2, 3}); 82 | Xs.push_back({11, 22, 33}); 83 | std::set> Ys; 84 | int n_subsets = 0; 85 | bool r = AllCombinedSubsetsOfSize(Xs, 3, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return true; }); 86 | EXPECT_TRUE(r); 87 | //for (const std::vector& ys : Ys) { 88 | // printf("ys = "); for (auto y : ys) { printf("%d ", y); } printf("\n"); 89 | //} 90 | EXPECT_EQ(Ys.size(), unsigned(n_subsets)); 91 | EXPECT_EQ(Ys.size(), unsigned(3*3+3*3)); 92 | for (int i = 1; i <= 3; ++i) { 93 | EXPECT_TRUE(Ys.find({i,11,22}) != Ys.end()); 94 | EXPECT_TRUE(Ys.find({i,11,33}) != Ys.end()); 95 | EXPECT_TRUE(Ys.find({i,22,33}) != Ys.end()); 96 | } 97 | for (int i = 11; i <= 33; i += 11) { 98 | EXPECT_TRUE(Ys.find({1,2,i}) != Ys.end()); 99 | EXPECT_TRUE(Ys.find({1,3,i}) != Ys.end()); 100 | EXPECT_TRUE(Ys.find({2,3,i}) != Ys.end()); 101 | } 102 | } 103 | 104 | TEST(SubsetsTest, subsets_one_ternary_set_cardinality_three) { 105 | std::vector> Xs; 106 | Xs.push_back({1, 2, 3}); 107 | std::set> Ys; 108 | int n_subsets = 0; 109 | bool r = AllCombinedSubsetsOfSize(Xs, 3, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return true; }); 110 | EXPECT_TRUE(r); 111 | EXPECT_EQ(n_subsets, 0); 112 | r = AllCombinedSubsetsOfSize(Xs, 3, [&](const std::vector& xs) { Ys.insert(xs); ++n_subsets; return false; }); 113 | EXPECT_TRUE(r); 114 | } 115 | 116 | } // namespace internal 117 | } // namespace limbo 118 | 119 | -------------------------------------------------------------------------------- /tests/syntax.cc: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2016 Christoph Schwering 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace limbo { 11 | 12 | using namespace limbo::format; 13 | using namespace limbo::format::cpp; 14 | 15 | #define REGISTER_SYMBOL(x) RegisterSymbol(x, #x) 16 | 17 | inline void RegisterSymbol(Term t, const std::string& n) { 18 | RegisterSymbol(t.symbol(), n); 19 | } 20 | 21 | TEST(Syntax, general) { 22 | // An extended version of this test is TEST(Formula, NF), which also tests the normal form. 23 | Context ctx; 24 | Term::Factory& tf = *ctx.tf(); 25 | auto BOOL = ctx.CreateNonrigidSort(); 26 | auto True = ctx.CreateName(BOOL); REGISTER_SYMBOL(True); 27 | auto HUMAN = ctx.CreateNonrigidSort(); 28 | auto Father = ctx.CreateFunction(HUMAN, 1); REGISTER_SYMBOL(Father); 29 | auto Mother = ctx.CreateFunction(HUMAN, 1); REGISTER_SYMBOL(Mother); 30 | auto IsParentOf = ctx.CreateFunction(BOOL, 2); REGISTER_SYMBOL(IsParentOf); 31 | auto John = ctx.CreateFunction(HUMAN, 0); REGISTER_SYMBOL(John); 32 | auto x = ctx.CreateVariable(HUMAN); REGISTER_SYMBOL(x); 33 | auto y = ctx.CreateVariable(HUMAN); REGISTER_SYMBOL(y); 34 | { 35 | auto phi = *Ex(x, John() == x); 36 | EXPECT_EQ(*phi, *Formula::Factory::Exists(x, Formula::Factory::Atomic(Clause{Literal::Eq(tf.CreateTerm(John, {}), x)}))); 37 | } 38 | { 39 | auto phi = *Fa(x, John() == x); 40 | EXPECT_EQ(*phi, *Formula::Factory::Not(Formula::Factory::Exists(x, Formula::Factory::Not(Formula::Factory::Atomic(Clause{Literal::Eq(tf.CreateTerm(John, {}), x)}))))); 41 | } 42 | { 43 | auto phi = *Fa(x, IsParentOf(Mother(x), x) == True && IsParentOf(Father(x), x) == True); 44 | EXPECT_EQ(*phi, *Formula::Factory::Not(Formula::Factory::Exists(x, Formula::Factory::Not(Formula::Factory::Not(Formula::Factory::Or( 45 | Formula::Factory::Not(Formula::Factory::Atomic(Clause{Literal::Eq(tf.CreateTerm(IsParentOf, {tf.CreateTerm(Mother, {x}), x}), True)})), 46 | Formula::Factory::Not(Formula::Factory::Atomic(Clause{Literal::Eq(tf.CreateTerm(IsParentOf, {tf.CreateTerm(Father, {x}), x}), True)})))))))); 47 | } 48 | { 49 | auto phi = *Fa(x, IsParentOf(x, y) == True && IsParentOf(Father(x), x) == True); 50 | EXPECT_EQ(*phi, *Formula::Factory::Not(Formula::Factory::Exists(x, Formula::Factory::Not(Formula::Factory::Factory::Not(Formula::Factory::Or( 51 | Formula::Factory::Not(Formula::Factory::Atomic(Clause{Literal::Eq(tf.CreateTerm(IsParentOf, {x, y}), True)})), 52 | Formula::Factory::Not(Formula::Factory::Atomic(Clause{Literal::Eq(tf.CreateTerm(IsParentOf, {tf.CreateTerm(Father, {x}), x}), True)})))))))); 53 | } 54 | 55 | { 56 | auto P = ctx.CreateFunction(BOOL, 1); REGISTER_SYMBOL(P); 57 | auto Q = ctx.CreateFunction(BOOL, 1); REGISTER_SYMBOL(P); 58 | auto phi = *(Ex(x, P(x) == True) >> Fa(y, Q(y) == True)); 59 | EXPECT_EQ(*phi, *Formula::Factory::Or( 60 | Formula::Factory::Not(Formula::Factory::Factory::Factory::Exists(x, Formula::Factory::Atomic(Clause{Literal::Eq(tf.CreateTerm(P, {x}), True)}))), 61 | Formula::Factory::Not(Formula::Factory::Exists(y, Formula::Factory::Not(Formula::Factory::Atomic(Clause{Literal::Eq(tf.CreateTerm(Q, {y}), True)})))))); 62 | } 63 | } 64 | 65 | } // namespace limbo 66 | 67 | -------------------------------------------------------------------------------- /tests/syntax.h: -------------------------------------------------------------------------------- 1 | // vim:filetype=cpp:textwidth=120:shiftwidth=2:softtabstop=2:expandtab 2 | // Copyright 2016-2017 Christoph Schwering 3 | // Licensed under the MIT license. See LICENSE file in the project root. 4 | // 5 | // Overloads some operators to provide a higher-level syntax for formulas. 6 | 7 | #ifndef LIMBO_FORMAT_CPP_SYNTAX_H_ 8 | #define LIMBO_FORMAT_CPP_SYNTAX_H_ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define MARK (std::cout << __FILE__ << ":" << __LINE__ << std::endl) 19 | 20 | namespace limbo { 21 | namespace format { 22 | namespace cpp { 23 | 24 | class HiTerm : public Term { 25 | public: 26 | HiTerm() = default; 27 | explicit HiTerm(Term t) : Term(t) {} 28 | }; 29 | 30 | class HiSymbol : public Symbol { 31 | public: 32 | HiSymbol(Term::Factory* tf, Symbol s) : Symbol(s), tf_(tf) {} 33 | 34 | template 35 | HiTerm operator()(Args... args) const { return HiTerm(tf_->CreateTerm(*this, Term::Vector({args...}))); } 36 | 37 | private: 38 | Term::Factory* const tf_; 39 | }; 40 | 41 | class HiFormula; 42 | 43 | class HiFormula { 44 | public: 45 | HiFormula(const Literal& a) : HiFormula(Clause({a})) {} // NOLINT 46 | HiFormula(const limbo::Clause& c) : HiFormula(Formula::Factory::Atomic(c)) {} // NOLINT 47 | HiFormula(const Formula::Ref& phi) : HiFormula(*phi) {} // NOLINT 48 | HiFormula(const Formula& phi) : phi_(phi.Clone()) {} // NOLINT 49 | 50 | operator Formula::Ref&() { return phi_; } 51 | operator const Formula::Ref&() const { return phi_; } 52 | 53 | operator Formula&() { return phi(); } 54 | operator const Formula&() const { return phi(); } 55 | 56 | Formula& phi() { return *phi_; } 57 | const Formula& phi() const { return *phi_; } 58 | 59 | Formula::Ref& operator->() { return phi_; } 60 | const Formula::Ref& operator->() const { return phi_; } 61 | 62 | Formula::Ref operator*() { return std::move(phi_); } 63 | 64 | Clause as_clause() const { 65 | internal::Maybe c = phi_->AsUnivClause(); 66 | assert(c); 67 | return c.val; 68 | } 69 | 70 | private: 71 | Formula::Ref phi_; 72 | }; 73 | 74 | class Context { 75 | public: 76 | Context() : solver_(sf(), tf()) {} 77 | 78 | Symbol::Sort CreateNonrigidSort() { 79 | return sf()->CreateNonrigidSort(); 80 | } 81 | Symbol::Sort CreateRigidSort() { 82 | return sf()->CreateRigidSort(); 83 | } 84 | HiTerm CreateName(Symbol::Sort sort) { 85 | return HiTerm(tf()->CreateTerm(sf()->CreateName(sort))); 86 | } 87 | HiTerm CreateVariable(Symbol::Sort sort) { 88 | return HiTerm(tf()->CreateTerm(sf()->CreateVariable(sort))); 89 | } 90 | HiSymbol CreateFunction(Symbol::Sort sort, Symbol::Arity arity) { 91 | return HiSymbol(tf(), sf()->CreateFunction(sort, arity)); 92 | } 93 | 94 | void AddClause(const Formula& phi) { 95 | Formula::Ref psi = phi.NF(sf(), tf()); 96 | internal::Maybe c = psi->AsUnivClause(); 97 | assert(c); 98 | solver_.grounder().AddClause(c.val); 99 | } 100 | 101 | void AddClause(const Clause& c) { 102 | solver_.grounder().AddClause(c); 103 | } 104 | 105 | Solver* solver() { return &solver_; } 106 | const Solver& solver() const { return solver_; } 107 | 108 | Symbol::Factory* sf() { return Symbol::Factory::Instance(); } 109 | Term::Factory* tf() { return Term::Factory::Instance(); } 110 | 111 | private: 112 | Solver solver_; 113 | }; 114 | 115 | inline HiFormula operator==(HiTerm t1, HiTerm t2) { return HiFormula(Literal::Eq(t1, t2)); } 116 | inline HiFormula operator!=(HiTerm t1, HiTerm t2) { return HiFormula(Literal::Neq(t1, t2)); } 117 | 118 | inline HiFormula operator~(const HiFormula& phi) { return Formula::Factory::Not(phi.phi().Clone()); } 119 | inline HiFormula operator!(const HiFormula& phi) { return ~phi; } 120 | inline HiFormula operator||(const HiFormula& phi, const HiFormula& psi) { 121 | return Formula::Factory::Or(phi.phi().Clone(), psi.phi().Clone()); } 122 | inline HiFormula operator&&(const HiFormula& phi, const HiFormula& psi) { return ~(~phi || ~psi); } 123 | 124 | inline HiFormula operator>>(const HiFormula& phi, const HiFormula& psi) { return (~phi || psi); } 125 | inline HiFormula operator<<(const HiFormula& phi, const HiFormula& psi) { return (phi || ~psi); } 126 | 127 | inline HiFormula operator==(const HiFormula& phi, const HiFormula& psi) { return (phi >> psi) && (phi << psi); } 128 | 129 | inline HiFormula Ex(HiTerm x, const HiFormula& phi) { return Formula::Factory::Exists(x, phi.phi().Clone()); } 130 | inline HiFormula Fa(HiTerm x, const HiFormula& phi) { return ~Ex(x, ~phi); } 131 | 132 | } // namespace cpp 133 | } // namespace format 134 | } // namespace limbo 135 | 136 | #endif // LIMBO_FORMAT_CPP_SYNTAX_H_ 137 | 138 | --------------------------------------------------------------------------------