Skip to content

Testing system for Prolog programs on Flask+React. Useful for exam preparation

Notifications You must be signed in to change notification settings

m-danya/prolog-testing-system

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

prolog-testing-system

Тестирующая система для программ на Prolog и ХЛП

Система доступна по адресу ➡️ https://prolog-contest.ru ⬅️

Как пользоваться: выбрать задачу, написать код в окошке справа, выбрать язык (Prolog / ХЛП), отправить задачу на проверку, получить вердикт тестирующей системы с подробным выводом на всех тестах.

Тестирующая система предназначена для самоподготовки студентов 3 потока 4 курса ВМК МГУ к экзамену по курсу "Математическая логика и логическое программирование". Поскольку в курсе присутствует логическое программирование и существуют интерпретаторы языка Prolog, возникла идея создания системы автоматизированной проверки программ студентов на задачах из семинаров для полноценной поддержки "программистской" части курса. Для этого была проделана следующая работа:

  1. Исследованы особенности работы интерпретатора gprolog языка Prolog

Здесь требовалось требовалось осуществить вывод всех решений для запроса-теста (тестирующего предикат пользователя) с учётом произвольности количества переменных в запросе. Проблема была в том, что интерпретаторы Пролога выводят решения по одному, предлагая нажать ';' для вычисления и вывода очередного решения. Для решения этой проблемы был использован предикат setof(+Template, +Goal, -Set), причём в качестве аргумента Template подаются все используемые в запросе переменные (их пришлось парсить из текста теста в variables_list, см. ниже). Результат ожидается в переменной Result.

cat {{ test_file }} | sed --expression='s/^\(.*\)\.$/setof\({{ variables_list }},\1, Result\)\./g'

Таким образом, запрос descendant(X, dima). превращается в setof({{ variables_list }},descendant(X, dima), Result). = setof([X],descendant(X, dima), Result)., и ожидаемый ответ на такой запрос может быть таким:

Result = [[kolya],[max],[nastya],[sasha],[vasya],[vlad]]
yes

Также в некоторых заданиях предлагается реализовать предикаты, опираясь на то, что некоторые предикаты уже реализованы (father и много других из 5.1, not из задач 7 семинара). Эти предикаты были реализованы в отдельном файле, общем для набора тестов: shared_consult_data.pl.

  1. Реализована серверная часть на Python с использованием фреймворка Flask.

Поскольку интерепретатор есть для языка Prolog, а в курсе изучаются программы на ХЛП (синтаксически схожем языке), для удобства пользователей был реализован транслятор с ХЛП на Prolog. Для этого потребовалось рассмотреть все различия используемых в курсе подмножеств этих языков, в том числе повозиться с обработкой списков.

Бэкенд устойчив к различному роду ошибок, сообщает о проблемах в ответе на запрос, если что-то идёт не так. API спроектирован с заделом на возможное дальнейшее развитие. Код пару раз подвергался рефакторингу.

  1. Реализована клиентская часть в виде React JS приложения. Интерфейс достаточно адаптивен и функционален. Условия задач рендерятся из markdown-а, результаты тестирования представлены в наглядном виде, есть возможность загрузки решения из файла.

  2. Было подготовлено markdown-описание, работающее решение и тесты для многих задач с семинаров курса. Источник задач.

  3. Для удобства пользователей система была развёрнута в виде сайта: https://prolog-contest.ru.

Предварительно backend и frontend части проекта были Docker-изованы для возможности лёгкого запуска на любом компьютере. (см. Delevopment notes)

Если что-то не работает

  1. Не используйте Wi-Fi ВМиКа (не шутка, реально не получается достучаться до бэкенда на 3001 порте нашего домена)
  2. Проверьте, что написанная вами программа синтаксически корректна для выбранного языка (Prolog/ХЛП)
  3. Продолжайте ботать матлог
  4. Отдохните 10 минут и попробуйте снова
  5. Если сайт лежит, или не подгружается список задач, пишите сюда или сюда.

Содействие развитию проекта (contributing)

Мы надеемся, что система будет полезна для подготовки к экзамену и приветствуем любой вклад в развитие проекта. Этот вклад может состоять в добавлении новых задач в систему, например из расширенного сборника задач от авторов курса. Для этого нужно сделать fork репозитория, добавить папку для каждой задачи в api/tests (+ решение в папку api/examples) аналогично тому, как это сделано сейчас, и сделать pull request.

Ограничения при добавлении тестов:

  1. Пожалуйста не используйте заглавные буквы в строках. Они могут быть интерпретированы как переменные.
  2. Пожалуйста не используйте пробелы в тестовых строках (временно). Программы на ХЛП могут работать на них некорректно.

При написании кода на Python используйте black.

Если что-то непонятно, пишите сюда или сюда.

Development notes (ENG)

Running a setup with Docker (recommended)

Run frontend+backend with Docker:

# just filling in .env file, you can do it manually with any text editor
echo 'REACT_APP_BACKEND_URL=http://127.0.0.1:3001
BACKEND_PORT=3001
FRONTEND_PORT=8080
' > .env

docker-compose up --build -d

Then open localhost:8080 in your browser.

Running a setup without Docker

Run the backend:

sudo apt install gprolog python3-venv
cd api
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python api.py

Run the frontend:

# 0. install nodejs (version >= 16)
# 1. run this:
cd react-frontend
npm install
REACT_APP_BACKEND_URL=http://localhost:3001 npm start

API description

Currently, the pipeline is like this:

  1. Submitting the .pl file to the system
  2. Executing this program on a set of tests

Submitting a program

http://127.0.0.1:3001/submit with form field 'submission'

Response:

{
    "submission_id": "90c5b537-43f4-47e2-a1da-638a457c2b7f",
    "message": "Successfully submitted",
    "status": 200
}

Executing a program on a set of tests

POST http://127.0.0.1:3001/execute with args {"type": "gprolog", "task": "task_2", "submission_id": "90c5b537-43f4-47e2-a1da-638a457c2b7f"}

Response:

{
    "message": "Successfully executed",
    "result": [
        {
            "test_number": 1,
            "result": "WA: output mismatch",
            "output_lines": [
                "Length = 1",
                "yes"
            ],
            "correct_lines": [
                "Length = 0",
                "yes"
            ],
            "test_text": "...",
            "test_consult_text": "..."
        },
        {
            "test_number": 2,
            "result": "OK",
            "output_lines": [
                "Length = 3",
                "yes"
            ],
            "correct_lines": [
                "Length = 3",
                "yes"
            ],
            "test_text": "...",
            "test_consult_text": "..."
        },
        {
            "test_number": 3,
            "result": "TL",
            "output_lines": [],
            "correct_lines": [
                "Length = 2",
                "yes"
            ],
            "test_text": "...",
            "test_consult_text": "..."
        },
        {
            "test_number": 4,
            "result": "RE",
            "output_lines": [
                "exception: Fatal Error: local stack overflow (size: 16384 Kb, reached: 16383 Kb, environment variable used: LOCALSZ)"
            ],
            "correct_lines": [
                "Length = 4",
                "yes"
            ],
            "test_text": "...",
            "test_consult_text": "..."
        }
    ],
    "status": 200
}

Submitting and executing programs without a frontend

One can use api/submit_and_execute.sh script to submit and execute a solution like this:

./submit_and_execute.sh task_5_1 examples/task_5_1.pl

Also, api/submit.sh and api/execute.sh scripts are available:

$ ./submit.sh path/to/my_program.pl
{
    "submission_id": "2d666df2-20b5-42da-9303-279481677f57",
    "message": "Successfully submitted",
    "status": 200
}
$ ./execute.sh task_1 2d666df2-20b5-42da-9303-279481677f57
{
    "message": "Successfully executed",
    "result": [
        ......
    ],
    "status": 200
}

About

Testing system for Prolog programs on Flask+React. Useful for exam preparation

Resources

Stars

Watchers

Forks