January 22, 2020

Тестовое задание

Задание сроком на 1 месяц и стоимостью 300к тенге. Основная цель этого задания оценить 3 навыка: 1. уровень скорости обучения На сколько хорошо кандидат изучил новую концепцию программирования, новый язык программирования и базовые основы компьютерной лингвистики в рамках prolog за 2 месяца. 2. навык дизайна архитектуры софтверных проектов. Маштабируемость, читаемость, паттерны. 3. навык создания идей новых симуляции и их дизайна для оптимизации искусственного интеллекта. Источником вдохновления могут быть классические AI исследования, нейробиология, эволюционная психология, гносеология, эпистемология, аналитическая философия итд итп

Задание

Разработать мини фреймворк для генерации тасков по типу babi.

Реализовать 20 тасков которые представлены в babi.

Придумать 30 новых тасков.

Я не ожидаю что все 30 тасков будут уникальными бенчмарками каких либо когнитивных свойств. Если будут несколько действительно новых оригинальных тасков, то этого будет достаточным.

Фреймворк должен состоять из логического мира. Логический мир состоит из универсалии - свойства объектов и отношения между ними из которых состоит симуляция. А так же акторов которые могут изменять свойства объектов или их отношения.

Зачем придумывать так много тасков?

Смысл в том чтобы продумать максимально красивый фреймворк логического мира чтобы минимизировать время добавления нового таска. Авторы оригинального babi тупо захардкодили 20 тасков. Захардкодить 20 тасков на много быстрее чем спроектировать полноценный фреймворк походу решив несколько интересных проблем. Например design patterns для универсалии или проблемы коллизии в логическом программировании. А захардкодить 50 тасков уже не так быстро и на многоо нуднее, чем придумать фреймворк.

Как придумывать таски?

Тут полет фантазии. Можно взять теорию из психологии. Или классические принципы puzzle design. Можно подумать про важные компоненты интеллекта типо памяти, восприятия, воображения итп. Или из философии алфавит мыслей Лейбница.

Еще один способ придумывания новых тасков это использовать слова из обычного языка. Эти слова должны быть абстрактными и не должны быть универсалиями логического мира. Получается что то вроде трансцендентального идеализма, хотя сама идея написания логического мира это традиция номинализма ;-)

То есть возьмем предикат одинаковые. Это сугобо абстрактное слово которое является продуктом челоческого разума. В логическом мире могут быть вшиты такие предикаты как цвета - красный, черный, желтый, но никак не должен быть ни где вшит предикат одинаковый. Например таск - агенту нужно открыть ящик ключом. У него это не получилось. Так как все ключи в комнате одного цвета. У него спрашивают почему ты не смог открыть коробку. Он отвечает потому что все ключи одинаковые. Этот предикат будет является продуктом нейронной сети, а не логического мира.

Но все же самый простой способ это придумывать по аналогии с babi.

Логический мир

Простейшая архитектура может выглядеть так:

Модуль универсалии universal.pl где перечислены идеальные relations, objects. А так же actions (то что изменяет состояние объектов или отношении между объектами).

Модуль конструирования миров constructor.pl где создаются с помощью идеальных универсалии конкретные объекты и отношения между ними.

Модуль сэмплирования simulation.pl где сэмплируются конкретный таск. Каждый сэмпл имеет свою уникальную "траекторию" за счет комбинаторной сложности.

Модуль DCN рендеринга dcn_render.pl который является интерфейсом между логическим состоянием симуляции и конечным агентом в виде естественного языка. По сути это маппинг между логикой первого порядка и естественным языком с помощью definite clause grammar.

Подробнее про универсалии.

relations это простые отношения между объектами. Например отношение местоположения location(Obj, Place) - где Obj, Place это переменные, структуру которых нужно будет в дальнейшем ��пределить. Например это могут быть уникальные идентификаторы location(obj(1), room(1)) - где obj(1) и room(1) это айдишки.

objects это объекты (кек), но как их определить? - как набор свойств. Например дверь в простейшем мире может быть определена как тройка свойств - (door, state, color) и уникальный идентификатор Id. door это сущность двери, поэтому все конкретные двери симуляции будут обладать этим свойством (иначе это не двери), state это функциональное свойство двери, которое может принимать два значения opened или closed, color это свойство которое нужно чтобы агент мог различать двери. Уникальный идентификатор нужен нам чтобы не путать объекты в коде, но агент не должен иметь доступа к нему. Поэтому если цвета у двери одинаковые, то для агента они не различимы.

actions это динамика логического мира. Изменение его состояния это изменения свойств объектов или отношении между ними. Например:

open_door(DoorId):- retract(door_state(DoorId, closed)), assert(door_state(DoorId, opened)).

move(PersonId, NextRoomId):- retract(location(PersonId, CurrentRoomId)), assert(location(PersonId, NextRoomId)).

Оба примера выше достаточны для понимания сути, но не являются валидными actions для логического мира. open_door вообще не имеет актора - субъекта который выполняет данное действия. move имеет субъект актора, но и этого не достаточно, так как не определена геометрия мира, простейшая может быть представлена как граф, где ребра это двери между комнатами. Тогда нужно чекнуть есть ли дверь между CurrentRoomId и NextRoomId. Точь так же в open_door можно открыть дверь только если актор находится в той же комнате где и сама дверь.

Детерминированность и свобода воли.

Сам по себе логический мир полностью детерминирован. Изменения его состояния могут быть только с помощью actions. Каждый action должен иметь актора. Актор может быть natural/supernatural и со свободой воли. Например в нашей симуляции может быть сменяемость дня и ночи, тогда наш актор - natural и является детерминированной частью среды.

С другой стороны актор со свободой воли может быть не частью логического мира. Например это может быть стохастическая нейронная сеть которая совершает действия на основе текущего состояния симуляции. Или это может быть стороння программа на haskell.

Проблема коллизии и времени в логическом мире.

Так как в среде может быть больше одного актора. Появляется проблема коллизии, например два агента одновременно пытаются взять один объект. Решение этой проблемы может быть разным. Самое простое запретить одновременные действия, то есть сделать среду по типу turn-based game. В принципе это ок, если большинство тасков не теряют свой смысл. Но все же я рекомендую попробывать создать полноценную среду. Для этого понадобится изучить основные практики и design patterns в геймдев индустрии. В первую очередь это game loop и double buffer. Сама по себе это достаточно интересная задача в рамках логического программирования. Отличный ресурс для изучения: gameprogrammingpatterns.com.

Rendering - фронтенд и компьютерная лингвистика

Полное состояние среды определяется набором всех свойств объектов и отношении между ними. В принципе этого достаточно чтобы пускать агентов в среду и оптимизировать их. Но как упражнение советую сделать интерфейс в виде компьютерной лингвистики, так как этот навык сильно нужен будет в дальнейшем в реальной работе.