Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Выходит что-то вроде «человеческого» ассемблера, который обладает коммуникативной и интуитивно-наглядной функциями естественного языка (так, как использует все те же слова из естественного языка)
… речь пойдет все таки о плановом языке… коротый, в процессе развития, имеет возможность трансформироваться практически в естественный.
Насколько я понимаю, это доопределение будет чисто «внутренним», для интерпретатора или компилятора, который будет разбирать предложение с естественного языка во внутреннее древовидное представление.
Какие-нибудь примеры рабочих систем, чтоб пощупать, уже есть?Смотреть пока не на что, но код рабочий, отображает бегающую по кругу змейку в бесконечном цикле.
Можно доопределить, что при одинаковых вопросах первым идёт субъект, а вторым — объект.
выбирать тот, который имеет смысл в данном контексте.
электрон ?что есть ?что часть ?чего атом.
Что веселее — это то, что теперь вам надо создать в системе правило, что сущности, связанные отношением «а — это часть б», могут вступать в отношения «б имеет а» только в таких ролях.Ну а как же иначе.
Ну а как же иначе.
Сейчас вы уже касаетесь базы знаний, для которой (в частности) этот интерпретатор создается.
А где можно увидеть определение того, что такое «интенциональное программирование»?Информации по нему не много.
собственно, смысл конструкций интерпретатору как задавать?С исполнимыми инструкциями кода проблем нет. Для инструкций передачи информации нужна будет онтология.
Ну и в-третьих, в вашей последней конструкции как определить, атом имеет электрон, или электрон имеет атом?Слева от глагола актор (валентности «кто» и «что»), справа актант (валентности «кто» и «что»). При построении дерева делаются соответствующие пометки.
Информации по нему не много.
С исполнимыми инструкциями кода проблем нет.
Слева от глагола актор (валентности «кто» и «что»), справа актант (валентности «кто» и «что»).
Поэтому я переформулирую вопрос: что вы называете «интенциональным программированием», когда приводите список недостатков и достоинств в начале статьи? У мне, если честно, создается ощущение, что вы приравниваете его к «программированию на естественном языке».Интенциональное программирование должно ясно отображать намерение разработчика, то что он хотел получить в действительности от кода. Ну, скажем, программирование на естественном языке можно рассматривать, как подмножество вариантов интенционального.
И как же вы планируете это реализовать?Код на видео уже работает.
Еще одно ограничение, которое уводит вашу систему еще дальше от естественного языка.Нет, это свойство любого естественного языка. Все множество языков разбиваются на жесткий порядок субъект-глагол-объект (как в английском) и более-менее произвольный (как в русском).
Ну, скажем, программирование на естественном языке можно рассматривать, как подмножество вариантов интенционального.
Код на видео уже работает.
Нет, это свойство любого естественного языка.
Все множество языков разбиваются на жесткий порядок субъект-глагол-объект (как в английском)
Это не каноническая форма английского языка.
некоторых случаях, когда по смыслу понятно кто объект а кто субъект
Или вы хотите, чтобы я бросил все, что нужно реализовывать и сосредоточился на ненужной (в данном случае) проблеме перестановки слагаемых. Это не художественная литература, здесь такой проблемы нет и не нужно притягивать кота за яйца.
Ключевое слово — «понятно по смыслу».Ну какой смысл в простеньком интерпретаторе. При введении онтологий, эта проблема возможно решаема.
Я ничего не заявляю, просто предлагаю способ сделать конструкции более детерминированными, а парсинг более простым.
Чтобы одновременно и оперировать словами естественного языка и не заморачиваться с разбором всех его многообразий.
Тем самым вы делаете из естественного языка язык программирования.Скорее что-то среднее.
Так вы хотите оперировать словами естественного языка (что, в общем-то, делает большая часть языков программирования), или естественным языком?Они не предназначены одновременно и для выполнения кода и для передачи информации. Мне нужна дополнительная коммуникативная функция, свойственная для ЕЯ. Чем ближе к естественному, тем лучше, но можно выбрать и что-то промежуточное.
Скорее что-то среднее.
Они не предназначены одновременно и для выполнения кода и для передачи информации.
То есть ни то, ни другое.Или и то и другое. Это как вам угодно.
Это почему еще? AST — это информация в чистом виде.Ну так дерево приходится и мне строить, для каждой инструкции. Но уже после передачи ее через канал коммуникации, а не до. Домохозяйка не будет этим заниматься (оборачивать координаты посудного шкафа в XML или JSON), пытаясь объяснить роботу куда складывать помытую посуду.
Ну так дерево приходится и мне строить, для каждой инструкции. Но уже после передачи ее через канал коммуникации, а не до.
Домохозяйка не будет этим заниматься (оборачивать координаты посудного шкафа в XML или JSON),
А почему вы думаете, что у языков программирования это иначе?Я так не думаю, всем приходится строить дерево. Я просто не понял к чему вы упомянули про AST
Ни XML, ни JSON не являются языками программирования. При чем тут это?Тогда опять, при чем был AST. Хотя, не важно.
Я так не думаю, всем приходится строить дерево. Я просто не понял к чему вы упомянули про AST
Задача человека, на основе уже заложенного набора алгоритмов (используя некий язык) расширить (обучить) функциональные возможности механизма в процессе коммуникации.
Но в идеале, решение должно максимизировать функциональность механизма при минимальных усилиях человека.
Есть механизм, есть канал коммуникации, есть человек (среднестатистический, не програмист). Механизм обладает минимальным набором поведенческих алгоритмов и способен понимать некоторый язык через канал коммуникации (скажем пока текстовый). Задача человека, на основе уже заложенного набора алгоритмов (используя некий язык) расширить (обучить) функциональные возможности механизма в процессе коммуникации.
Но вообще, конечно, вы сейчас описали программирование, как оно есть.Если не учитывать, что в программировании как оно есть, человек должен предварительно специально обучаться, потому как оперирует он спец. инструкциями, а так же непостредственными объектами кода, а не объектами предметной области
На их основе можно создать набор более высокоуровневых инструкций (используя мощь естественного языка).
Далее возвращаемся к вопросу, как вы это собираетесь делать.Набор инструкций все таки конечен. Если что-то системе не ясно, она всегда может спросить. Можно хранить базу синонимов. По частным случаям нужно будет разбираться отдельно.
Набор инструкций все таки конечен.
Если что-то системе не ясно, она всегда может спросить.
Дело не в инструкциях как таковых, а в структуре языке.Потому и использовал упрощение в виде эксплицитных валентностей.
Хуже, когда системе ясно, но ясно неправильно.От этого никакой ЯП не застрахован, иначе отладчиков бы не существовало.
Потому и использовал упрощение в виде эксплицитных валентностей.
От этого никакой ЯП не застрахован, иначе отладчиков бы не существовало.
Угу, и тем самым превратили естественный язык в язык программирования с именованными аргументами методов.Программирования и обмена информацией, что важно. ЯП — для программирования, ЕЯ — для обмена информацией. Тут получилось пересечение свойств, что и требуется.
каждая инструкция однозначно отражает намерение разработчика, ее написавшего
Пример кода в видео выглядит гораздо сложнее кода на обычных ЯП…Там все глаголы только в инфинитиве, валентности только в м. роде и ед. числе. Это потому, что еще не все реализовано в парсере. Обработка падежных форм тоже не реализована, все в им. падеже. Время — только настоящее. Эти проблемы буду решаться. Хотя, возможно вы «в общем» имели в виду. Это скорее связано с тем, что смысл некоторых инструкций нужно объяснять, так как они связаны еще с одной идеей: если присмотреться, в коде нет инструкций циклов и условных переходов.
если присмотреться, в коде нет инструкций циклов и условных переходов.
Зато есть условия, которые дают тот же эффект.
Создание блока с инстукциями описывающими условия предполагается автоматизировать.
На основании каких входных данных?Это тема для отдельной статьи, пожалуй. Но если кратко, то у триггеров, из которых состоят условия будут символические имена, даже не имена, а конструкции, выражаемые предложением. Поиск процедуры, код которой нужно править будет выполнятся ассоциативно, на основе набора символических имен.
1. Текущая секция змейки является головой
2. Направление движения змейки — вниз
3. Голова змейки находится в самой нижней клетке поля
match state with
| (currentSection, direction, headPosition)
when (currentSection |> isHead)
and (direction |> isDown)
and (headPosition |> isAtLowestBound)
-> ...
Скажем, вызов функции sort вместо вписывания пары циклов «пузырька» повышает интенциональность.
SELECT FROM Authors WHERE Name CONTAINS 'Gaiman'
^(\t*)создавать \?что \(=(.+) \?что иметь \?что имя \?какой (.+)\)\.\s*$
$1$GLOBALS['$3'] = ['имя' => '$3', 'значение' => [null]]; $$$3 = &$GLOBALS['$3']; $$$2 = &$$$3;
^(\t*)добавлять \?что (.+) \?чего (.+)\.\s*$
$1$$$3['значение'][] = null; $$$2 = &$$$3['значение'][count\($$$3['значение']\) - 1];
^(\t*)использовать \?что ([^\s\(\)]+) \(\?чего (.+), \?какой (\d+)\)\.\s*$
$1$$$2 = &$$$3['значение'][$4];
^(\t*)использовать \?что ([^\s\(\)]+) \(\?чего (.+), \?какой ([^\s\(\)]+)\)\.\s*$
$1$$$2 = &$$$3['значение'][$$$4['значение']];
элемент \(\?чего ([^\s\(\)]+), \?какой ([\d]+)\)
$$$1['значение'][$2]
элемент \(\?чего ([^\s\(\)]+), \?какой ([\w]+)\)
$$$1['значение'][$$$2['значение']]
^(\t*)устанавливать \?что (.+) \(\?чего (.+), \?какой (\d+)\)\.\s*$
$1set_value\($$$3, '$2', $4\);
^(\t*)устанавливать \?что (.+) \(\?чего (.+), \?какой (.+)\)\.\s*$
$1set_value\($$$3, '$2', $$$4['значение']\);
"\['значение'\]
"
выполнять \?что \(=процедура \?что иметь \?что имя \?какой Snake.(.+)\)\.
$1\(\);
\\"
"
^(\t*)регистрировать \?что ([^\s\(\)]+) \(\?на-что ([^\s\(\)]+), \?для-чего ([^\s\(\)]+)\)\.\s*$
$1unset\($$$2\); register\($$$2, '$3', $$$4\);
^(\t*)регистрировать \?что ([^\s\(\)]+) \(\?какой (.+), \?на-что ([^\s\(\)]+) \?какой (.+), \?для-чего (.+)\)\.\s*$
$1unset\($$$2\); register_ex\($$$2, $3, '$4', $5, $$$6\);
^(\t*)присоединять \(\?что ([^\s\(\)]+), \?к-чему ([^\s\(\)]+)\)\.\s*$
$1attach\($$$2, '$3'\);
^(\t*)печатать \?что значение \?какой (.+)\.\s*$
$1echo $2;
^(\t*)печатать \?что ([^\s\(\)]+) \?чего (.+)\.\s*$
$1echo $$$3['$2'];
\$\$
$
^(\t*)преобразовывать \(\?что (.+) \?как-что (.+), \?во-что (.+) \?как-что буква\)\.\s*$
$1$$$4 = $$$2;
^(\t*)увеличивать \(\?что (.+) \?чего (.+), \?на-сколько (\d+)\)\.\s*$
$1set_value\($$$3, '$2', $$$3['$2'] + $4\);
^(\t*)уменьшать \(\?что (.+) \?чего (.+), \?на-сколько (\d+)\)\.\s*$
$1set_value\($$$3, '$2', $$$3['$2'] - $4\);
\$\$
$
^(\t*)процедура (.+)\s*$
$1}\n\n$1function $2\(\)\n$1{\n\t\tforeach \($GLOBALS as $key => $value\) { $$$$key = &$GLOBALS[$key]; }\n
\$"
"
\#
//
<?php
global $triggers, $allow_triggers;
$triggers = [];
$allow_triggers = true;
function register(&$trigger, $type, &$variable)
{
global $triggers;
$trigger = [
'type' => $type,
'reference' => &$variable,
'property' => 'значение',
'const_value' => null,
'conditions' => [],
];
$triggers[] = &$trigger;
}
function register_ex(&$trigger, $type, $property, $const_value, &$variable)
{
global $triggers;
$trigger = [
'type' => $type,
'reference' => &$variable,
'property' => $property,
'const_value' => $const_value,
'conditions' => [],
];
$triggers[] = &$trigger;
}
function attach(&$trigger, $condition_name)
{
$trigger['conditions'][] = $condition_name;
}
function ref_equals(&$a, &$b)
{
$t = $a;
$a = 1;
$eq1 = ($b === $a);
$a = 2;
$eq2 = ($b === $a);
$a = $t;
return ($eq1 && $eq2);
}
function process_triggers(&$variable, $old_value, $new_value)
{
global $triggers, $allow_triggers;
if (!isset($variable['имя'])) return;
if (!$allow_triggers) return;
$allow_triggers = false;
$handlers = [];
foreach ($triggers as $trigger) {
if (!ref_equals($trigger['reference'], $variable)) continue;
if (
$trigger['type'] == 'изменение' && $old_value != $new_value
|| $trigger['type'] == '==' && $new_value == $trigger['const_value']
|| $trigger['type'] == '!=' && $new_value != $trigger['const_value']
)
{
foreach ($trigger['conditions'] as $condition_name) {
if (!isset($GLOBALS[$condition_name])) continue;
$condition = $GLOBALS[$condition_name];
$handlers[] = [
'обработчик' => $condition['обработчик'],
'приоритет' => isset($condition['приоритет']) ? $condition['приоритет'] : 0,
];
}
if (isset($trigger['обработчик']) && isset($trigger['приоритет'])) {
$handlers[] = [
'обработчик' => $trigger['обработчик'],
'приоритет' => isset($trigger['приоритет']) ? $trigger['приоритет'] : 0,
];
}
}
}
usort($handlers, function($a, $b) {
if ($a['приоритет'] == $b['приоритет']) return 0;
return ($a['приоритет'] > $b['приоритет'] ? -1 : 1);
});
foreach ($handlers as $handler) {
eval($handler['обработчик']);
}
$allow_triggers = true;
}
function set_value(&$variable, $property, $new_value)
{
$old_value = isset($variable[$property]) ? $variable[$property] : null;
$variable[$property] = $new_value;
process_triggers($variable, $old_value, $new_value);
}
function Init()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Инициализация при загрузке модуля
$GLOBALS['XList'] = ['имя' => 'XList', 'значение' => [null]]; $XList = &$GLOBALS['XList']; $список = &$XList;
$список['значение'][] = null; $элемент = &$список['значение'][count($список['значение']) - 1];
set_value($элемент, 'значение', 1);
$список['значение'][] = null; $элемент = &$список['значение'][count($список['значение']) - 1];
set_value($элемент, 'значение', 1);
$список['значение'][] = null; $элемент = &$список['значение'][count($список['значение']) - 1];
set_value($элемент, 'значение', 1);
$GLOBALS['YList'] = ['имя' => 'YList', 'значение' => [null]]; $YList = &$GLOBALS['YList']; $список = &$YList;
$список['значение'][] = null; $элемент = &$список['значение'][count($список['значение']) - 1];
set_value($элемент, 'значение', 1);
$список['значение'][] = null; $элемент = &$список['значение'][count($список['значение']) - 1];
set_value($элемент, 'значение', 2);
$список['значение'][] = null; $элемент = &$список['значение'][count($список['значение']) - 1];
set_value($элемент, 'значение', 3);
$GLOBALS['SnakeLength'] = ['имя' => 'SnakeLength', 'значение' => [null]]; $SnakeLength = &$GLOBALS['SnakeLength']; $поле = &$SnakeLength;
set_value($поле, 'значение', 3);
$GLOBALS['Temp'] = ['имя' => 'Temp', 'значение' => [null]]; $Temp = &$GLOBALS['Temp']; $поле = &$Temp;
$GLOBALS['ListIterator'] = ['имя' => 'ListIterator', 'значение' => [null]]; $ListIterator = &$GLOBALS['ListIterator']; $поле = &$ListIterator;
$GLOBALS['C1'] = ['имя' => 'C1', 'значение' => [null]]; $C1 = &$GLOBALS['C1']; $условие = &$C1;
set_value($условие, 'обработчик', "СP001();");
set_value($условие, 'приоритет', 3);
$GLOBALS['C2'] = ['имя' => 'C2', 'значение' => [null]]; $C2 = &$GLOBALS['C2']; $условие = &$C2;
set_value($условие, 'обработчик', "СP002();");
set_value($условие, 'приоритет', 2);
$GLOBALS['C3'] = ['имя' => 'C3', 'значение' => [null]]; $C3 = &$GLOBALS['C3']; $условие = &$C3;
set_value($условие, 'обработчик', "СP003();");
set_value($условие, 'приоритет', 2);
$GLOBALS['C4'] = ['имя' => 'C4', 'значение' => [null]]; $C4 = &$GLOBALS['C4']; $условие = &$C4;
set_value($условие, 'обработчик', "СP004();");
set_value($условие, 'приоритет', 2);
$GLOBALS['C5'] = ['имя' => 'C5', 'значение' => [null]]; $C5 = &$GLOBALS['C5']; $условие = &$C5;
set_value($условие, 'обработчик', "СP005();");
set_value($условие, 'приоритет', 2);
$GLOBALS['C6'] = ['имя' => 'C6', 'значение' => [null]]; $C6 = &$GLOBALS['C6']; $условие = &$C6;
set_value($условие, 'обработчик', "СP006();");
$GLOBALS['C7'] = ['имя' => 'C7', 'значение' => [null]]; $C7 = &$GLOBALS['C7']; $условие = &$C7;
set_value($условие, 'обработчик', "СP007();");
$GLOBALS['C8'] = ['имя' => 'C8', 'значение' => [null]]; $C8 = &$GLOBALS['C8']; $условие = &$C8;
set_value($условие, 'обработчик', "СP008();");
$GLOBALS['C9'] = ['имя' => 'C9', 'значение' => [null]]; $C9 = &$GLOBALS['C9']; $условие = &$C9;
set_value($условие, 'обработчик', "СP009();");
unset($триггер); register($триггер, 'изменение', $поле);
attach($триггер, 'C1');
unset($триггер); register_ex($триггер, "!=", 'значение', 3, $поле);
attach($триггер, 'C1');
unset($триггер); register_ex($триггер, "==", 'значение', 1, $поле);
set_value($триггер, 'обработчик', "TP001();");
set_value($триггер, 'приоритет', 1);
unset($триггер); register_ex($триггер, "==", 'значение', 3, $поле);
set_value($триггер, 'обработчик', "TP002();");
set_value($триггер, 'приоритет', 3);
attach($триггер, 'C2');
attach($триггер, 'C3');
attach($триггер, 'C4');
attach($триггер, 'C5');
attach($триггер, 'C6');
attach($триггер, 'C7');
attach($триггер, 'C8');
attach($триггер, 'C9');
$GLOBALS['Direction'] = ['имя' => 'Direction', 'значение' => [null]]; $Direction = &$GLOBALS['Direction']; $поле = &$Direction;
unset($триггер); register_ex($триггер, "==", 'значение', 1, $поле);
attach($триггер, 'C2');
attach($триггер, 'C6');
unset($триггер); register_ex($триггер, "==", 'значение', 2, $поле);
attach($триггер, 'C3');
attach($триггер, 'C8');
unset($триггер); register_ex($триггер, "==", 'значение', 3, $поле);
attach($триггер, 'C4');
attach($триггер, 'C9');
unset($триггер); register_ex($триггер, "==", 'значение', 4, $поле);
attach($триггер, 'C5');
attach($триггер, 'C7');
unset($триггер); register_ex($триггер, "==", 'значение', 1, $YList['значение'][3]);
attach($триггер, 'C8');
unset($триггер); register_ex($триггер, "==", 'значение', 10, $YList['значение'][3]);
attach($триггер, 'C6');
unset($триггер); register_ex($триггер, "==", 'значение', 1, $XList['значение'][3]);
attach($триггер, 'C9');
unset($триггер); register_ex($триггер, "==", 'значение', 10, $XList['значение'][3]);
attach($триггер, 'C7');
set_value($ListIterator, 'значение', 1);
set_value($Direction, 'значение', 1);
echo "INIT[10:10]\n";
echo "SET[A1]\n";
echo "SET[A2]\n";
echo "SET[A3]\n";
echo "REFR[]\n";
}
function TP001()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Триггер ListIterator==1
echo "CLR[";
$элемент = &$XList['значение'][1];
$Temp = $элемент;
echo $Temp['значение'];
$элемент = &$YList['значение'][$ListIterator['значение']];
echo $элемент['значение'];
echo "]\n";
}
function TP002()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Триггер ListIterator==3
set_value($ListIterator, 'значение', 1);
echo "REFR[]\n";
}
function СP001()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Условие (ListIterator, ListIterator!=3)
set_value($Temp, 'значение', $ListIterator['значение']);
set_value($Temp, 'значение', $Temp['значение'] + 1);
$элемент = &$XList['значение'][$Temp['значение']];
set_value($XList['значение'][$ListIterator['значение']], 'значение', $элемент['значение']);
$элемент = &$YList['значение'][$Temp['значение']];
set_value($YList['значение'][$ListIterator['значение']], 'значение', $элемент['значение']);
set_value($ListIterator, 'значение', $ListIterator['значение'] + 1);
}
function СP002()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Условие (ListIterator==3, Direction==1)
$элемент = &$XList['значение'][$ListIterator['значение']];
$Temp = $элемент;
set_value($YList['значение'][$ListIterator['значение']], 'значение', $YList['значение'][$ListIterator['значение']]['значение'] + 1);
echo "SET[";
echo $Temp['значение'];
echo $YList['значение'][$ListIterator['значение']]['значение'];
echo "]\n";
}
function СP003()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Условие (ListIterator==3, Direction==1)
$элемент = &$XList['значение'][$ListIterator['значение']];
$Temp = $элемент;
set_value($YList['значение'][$ListIterator['значение']], 'значение', $YList['значение'][$ListIterator['значение']]['значение'] - 1);
echo "SET[";
echo $Temp['значение'];
echo $YList['значение'][$ListIterator['значение']]['значение'];
echo "]\n";
}
function СP004()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Условие (ListIterator==3, Direction==4)
set_value($XList['значение'][$ListIterator['значение']], 'значение', $XList['значение'][$ListIterator['значение']]['значение'] - 1);
$элемент = &$XList['значение'][$ListIterator['значение']];
$Temp = $элемент;
echo "SET[";
echo $Temp['значение'];
echo $YList['значение'][$ListIterator['значение']]['значение'];
echo "]\n";
}
function СP005()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Условие (ListIterator==3, Direction==4)
set_value($XList['значение'][$ListIterator['значение']], 'значение', $XList['значение'][$ListIterator['значение']]['значение'] + 1);
$элемент = &$XList['значение'][$ListIterator['значение']];
$Temp = $элемент;
echo "SET[";
echo $Temp['значение'];
echo $YList['значение'][$ListIterator['значение']]['значение'];
echo "]\n";
}
function СP006()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Условие (ListIterator==3, Direction==1, Y[3]==10)
set_value($Direction, 'значение', 4);
}
function СP007()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Условие (ListIterator==3, Direction==4, X[3]==10)
set_value($Direction, 'значение', 2);
}
function СP008()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Условие (ListIterator==3, Direction==2, Y[3]==1)
set_value($Direction, 'значение', 3);
}
function СP009()
{
foreach ($GLOBALS as $key => $value) { $$key = &$GLOBALS[$key]; }
// Условие (ListIterator==3, Direction==3, X[3]==1)
set_value($Direction, 'значение', 1);
}
Init();
После добавления флага для запрещения срабатывания триггеров внутри триггеровЭто вы правильно сделали.
программа выдает строку «CLR[13] SET[14] INIT[10:10] SET[A1] SET[A2] SET[A3] REFR[] ».Должно быть так:
Задача была не избавиться от императивности, а скорее наоборот, сохранить ее
Чтобы язык и выполняться мог и информацию переносить.
Тогда вы не сможете «программировать через описание». Да с интенциональностью это плохо сочетается.Почему не смогу?
Для переноса информации ничто из того, что вы используете, не обязательно (и не нужно).Что по вашему мнению я должен использовать вместо всего этого?
Почему не смогу?
Что по вашему мнению я должен использовать вместо всего этого?
Потому что описание (в обычном его понимании) — это декларативное, а не императивное программирование.В случае с обучением с учителем нужно как декларативное, так и императивное.
Структур данных придумано достаточно. В частности, все, что вы используете, заменяется обычным списком.Списком из чего?
В случае с обучением с учителем нужно как декларативное, так и императивное.
Списком из чего?
Список как структура данных.А кто должен будет заполнять этот список-структуру? Непрограммист сможет это делать?
А кто должен будет заполнять этот список-структуру?
Непрограммист сможет это делать?
Вы же не ожидаете, что непрограммист будет формулировать ваши инструкции с указанием валентностей?Сначала будет. Я же говорю, для человека это вообще не проблема, а для машины большое упрощение. Потом система сама будет их заполнять. Предвидя следующий вопрос «А как?» скажу, что не знаю. Вернее, большинство валентностей заполнимы по предлогам и союзам:
"Переместить (?откуда Х, ?куда Y)."= «Переместить из X в Y»
интерпретатор насколько статичен? Если подобно человеку он постоянно накапливает знания, то результат работы программы может измениться от прогона к прогону.Это можно считать плюсом, если с каждым прогоном изменение поведения программы приближает его к цели/целям.
Также язык сценариев warcraft 3 тоже довольно человекочитаем.
Не совсем понял, как ваша идея соотносится с литературным программированием.Каким-то образом касается наверное, но они похоже обрабатывают именно естественный язык, а это непросто.
как вы относитесь к тому, чтобы словами описывать цвет и размер кнопок, чуть правее поля ввода имени пользователя словами?Не очень хорошо отношусь, для уровня представления есть CSS, кажется другого для этой ниши и не нужно. А лучше всего, еще и генерить CSS автоматически в визуальном редакторе.
Задача человека обучить правилам игры не прибегая (совсем, или практически) к непосредственному программированию.
обучение компьютера играть в игры
Например, во всех играх есть игроки, их может быть определенное количество. Они могут играть разные роли. В игре могут быть вспомогательные объекты (доска, фишки, фигуры, карты, кубики). Игроки в определенной последовательности что-то делают. Делают с объектами (кидают кубик) или без объектов (загадывают число, говорят что-то другим игрокам).Да, все так.
В каждой игре должна быть какая-то целевая функция, возможные окончания (выигрыш, проигрыш, ничья) или промежуточные этапы.
Задача человека обучить правилам игры не прибегая (совсем, или практически) к непосредственному программированию. Т.е. речь о коммуникативном программировании объяснением, как это происходит, когда один человек учит другого правилам игры.Ну тут тоже можно ничего не объясняя показать много сыгранных партий(в удобной компьютеру форме). Причем можно даже не объяснять кто выиграл, тогда просто будет обучение одновременно паре игр(шашки/поддавки).
Ну тут тоже можно ничего не объясняя показать много сыгранных партий(в удобной компьютеру форме). Причем можно даже не объяснять кто выиграл, тогда просто будет обучение одновременно паре игр(шашки/поддавки).Это проблема обучения без учителя, обучения наблюдением. И эта задача из области СИИ (сильного ИИ), а не ИИ, она затрагивает умение естественного интеллекта к ассоциативной классиикации. Причем к классификации всего и вся. Для этого нужно выявить принципы работы такого умения, а они насколько я знаю пока неизвестны (именно универсальный классификатор всего и вся).
человек вступил в клуб
если правильно понял, то именно это и понимает автор под событиями
«Двигатель запущен» — это одновременно событие и состояниеЭто событие. А «двигатель работает» это состояние. Все зависит от того, что важно для системы, то что двигатель был запущен, или то, что он работает именно сейчас.
если правильно понял, то именно это и понимает автор под событиями
Тогда весь поток управления — не более чем рекоммендуемая последовательность проверок, которую можно заменить на систему приоритетов.Можно и так сказать.
Прошедшее завершенное время глагола обозначает действие, которое было совершено в прошлом. Для того, чтобы показать завершенность действия к глаголу присоединяется суффикс 了 le
Но в паре...предлагаю термин широкое программирование(wide programming), а вместе с ним еще парочку: идентификатор ситуации, событийный адрес, ассоциативный адрес
предлагаю термин широкое программирование(wide programming)я бы сказал (и в шутку и в серьез) что это естественное программирование, поскольку естественный язык (ну хорошо, близкий к нему, пока что) это естественно для человека. А объяснение поведения через описание ситуции, в которой это поведение применимо, естественно для человека не менее, чем естественный язык, на котором оно объясняется.
Внос изменений будет таким же сложным, как обычное программирование. Сначала человек месяцы это читает и отмечает, где что расписано.Как раз делается попытка ухода от этого. В коде не нужно будет разбираться. Человек работает с одной, конкретной ситуацией, поведение, при возникновении которой, он хотел бы изменить.
Человек работает с одной, конкретной ситуацией, поведение, при возникновении которой, он хотел бы изменить.
Угу. А как определить, какая ситуация ему нужна?Процитирую то, что уже писал выше, может быть на этот раз вы прочтете все.
Что важнее — как определить, что изменится, когда он внесет свои изменения?Всякое изменение само стремится себя проявить, вам ли, как разработчику, этого и не знать.
Например, мы хотим запросить (и изменить ее код) у системы процедуру, которая вызывается в ситуции
Всякое изменение само стремится себя проявить, вам ли, как разработчику, этого и не знать.
Но откуда мы возьмем набор входных условий?Для этого и нужен естественный язык. Набор входных условий описывает на нем человек:
Вот как раз как разработчик я очень хорошо знаю, что в любой сколь-либо сложной системе изменение может проявиться не сразу, и неочевидным образом. Иными словами, чем сложнее система, тем, при прочих равных, вероятнее в ней эффект бабочки.Потому то и надо к программированию сложных систем подходить с точки зрения ситуаций.
Для этого и нужен естественный язык. Набор входных условий описывает на нем человек:
1. Текущая секция змейки является головой
2. Направление движения змейки — вниз
3. Голова змейки находится в самой нижней клетке поля
Если он все их протестирует, то откуда возникнет эффект бабочки?
А откуда он их возьмет?Из головы.
Оттуда, что тестировать поведение системы надо будет для всех ситуаций, в которых затронуты перечисленные условия, а (а) этот список надо будет откуда-то взять и (б) он может оказаться очень большим.Конечно для всех. А что неполное тестирование когда-то красило тестировщика?
Более того, внесенное вами поведение может провоцировать новые ситуации и новые реакции, и как это протестировать?Это только в классическом программировании. В ситуационном, если разработчик добавил новую ситуацию, она должна попадать в документацию и полноценно тестироваться.
Вы совершенно зря проигнорировали мой пример с пересекающимися условиями.Возможно случайно, как ситуации могут пересекаться?
Из головы.
Конечно для всех. А что неполное тестирование когда-то красило тестировщика?
За одну итерацию исправления он врядли будет большим.
В ситуационном, если разработчик добавил новую ситуацию, она должна попадать в документацию и полноценно тестироваться.
Возможно случайно, как ситуации могут пересекаться?
Проблема в том, что вы усложняете его работу.Нет, я заставляю его делать свою работу полностью, а не филонить, проводя рабочее время на хабре.
Вы не можете это предсказать.Могу, аналитик передает вполне конкретный и ограниченный перечень доработок программисту. Он в свою очередь тестировщику.
В ситуационном, если разработчик добавил новую ситуацию, она должна попадать в документацию и полноценно тестироваться.Регламентом. А про побочные эффеты мне не известно. Когда они выявятся, а это будет не скоро, я эти проблемы конечно же опишу. Пока нечего сказать, возможно Вы правы.
«предположим, в системе уже определена реакция на состояние «направление движения — вниз». Теперь мы хотим определить реакцию на состояние «направление движения — вниз, и позиция в нижнем ряду». Как эти две реакции будут друг с другом соотноситьсяВопрос хороший. В данном случае нужно будет править одновременно 2 обработчика. Вернее перенести часть из первого во второй. Надо будет думать, как это автоматизировать. Пока еще рано. Возможно, что автоматизировать не получиться.
Могу, аналитик передает вполне конкретный и ограниченный перечень доработок программисту. Он в свою очередь тестировщику.
Регламентом.
А про побочные эффеты мне не известно.
В данном случае нужно будет править одновременно 2 обработчика. Вернее перенести часть из первого во второй.
Надо будет думать, как это автоматизировать. Пока еще рано. Возможно, что автоматизировать не получиться.
Обработчики у них разные.
который при специфическом сочетании условий даст побочный эффект?Такого быть не должно. Обработчики не пересекаются.
В вашей (описанной) системе нет ничего, что их предотвращает. Следовательно, они не только возможны, но и будут.Такие комментарии отбивают охоту отвечать. Вы же понимаете, что то, чего нет, может появится. Проблемы решаются по мере поступления. А на данный момент их и так хватает.
Откуда вы это знаете?Потому что сталкивался уже с этим.
Не получится. Следовательно, каждый раз программисту надо будет анализировать уже существующие обработчики, пересекающиеся по событиям. Следовательно, работать с одной конкретной ситуацией не выйдет.Возможно. Но это все равно гораздо легче, чем править линейную простыню.
Да понятно, что разные, но вызывается ли первый, когда вызывается второй?Если понятно, то это странный вопрос.
Такого быть не должно. Обработчики не пересекаются.
Такие комментарии отбивают охоту отвечать. Вы же понимаете, что то, чего нет, может появится.
Потому что сталкивался уже с этим.
Возможно. Но это все равно гораздо легче, чем править линейную простыню.
Если понятно, то это странный вопрос.
Во-первых, пересекаются, мы это выяснили.Когда выяснили? Они могут пересекаться только если создается новое условие.
(1) при каждом списании 100 рублей со счета, на связанный счет должен начисляться 1 рубль (бонусная система)Это отдельная подпрограмма, соизмеримая со змейкой. Но она реализуема.
(2) раз в месяц со счета должны списываться 1000 рублей (регулярный платеж)
И сразу возникает вопрос, как вы будете бороться с возрастанием сложности в таком случае.Модульностью
И уже успели обобщить свой опыт на все возможные ситуацииДа, пока не появились ситуации не вписывающиеся в опыт.
О какой «линейной простыне» вы говорите?Об классическом программирование: if, for, while…
Обработчики — разные, но их условия совпадают. По логике, должны вызываться оба. Это так, или нет?Не может быть так. У каждого условия (ситуации) свой обработчик.
Когда выяснили? Они могут пересекаться только если создается новое условие.
Это отдельная подпрограмма, соизмеримая со змейкой. Но она реализуема.
Об классическом программирование: if, for, while…
Не может быть так. У каждого условия (ситуации) свой обработчик.
Могут же, этого достаточно.Не могут. Под пересечением я имел в виду не одновременный вызов, а то, что часть кода из одного может мигрировать в другой (новый). Это же разные вещи.
Это же два разных условия, правильно? И два разных обработчика, так?Боюсь там будет побольше двух условий (и обработчиков). Было бы
Знаете, структурное программирование — которое избавляет от линейных простыней — давно придумали.Структурное программирование призвано уменьшить код блока (процедуры/функции).
Во-первых, тезис «у каждой ситуации свой обработчик» не запрещает иметь два обработчика на одну ситуацию.Да как же у одной ситуации может быть больше одного обработчика??
Во-вторых, если вы введете ограничение «на одну ситуацию один обработчик», вы резко уменьшите поддерживаемость системы (потому что бывают независимые обработчики).Ничего не понял.
Наконец, в-третьих, я говорил об обработчиках, условия которых совпадают, но не идентичны. Пример был выше: условиями одной ситуации является «движение вниз», условиями другой — «движение вниз и позиция в нижнем краю». Это же два разных обработчика?Ну конечно. Первое это триггер, у него свой обработчик. Второе это условие из двух триггеров, у этого условия свой обработчик.
Боюсь там будет побольше двух условий (и обработчиков). Было бы
так просто я бы сразу код написал. Но то, что они разные это точно.
Ситуационное программирование призвано свести код блока к 1-2 строкам.
Да как же у одной ситуации может быть больше одного обработчика?
Ничего не понял.
Ну конечно. Первое это триггер, у него свой обработчик. Второе это условие из двух триггеров, у этого условия свой обработчик.
Прекрасно. И если вы обратите внимание, то увидите, что в рамках одного обработчика совершается действие, которое приводит к инициации другого. Ведь так?Похоже, что так.
Что такого предлагает ситуационное программирование, что позволяет радикально уменьшить размер (семантически эквивалентного) блока кода?Я не про семантически эквивалентный блок, а про процедуру (функцию), как блок. Правда в СП количество процедур действительно будет больше.
Это два независимых правила, реализующих различные бизнес-задачи. Как следствие, SRP говорит нам, что они должны быть в разных обработчикахЭто два алгоритма, которые будут реализованы в разных подпрограммах, но вызваны в рамках одного обработчика, который вызывается для ситуации «Транзакция по счету завершилась».
Пример выше.Внутри каждого обработчика можно вызывать друг за другом другие поддпрограммы, или выполнять манипуляции с локальными данными.
Так вот, когда состояние системы удовлетворяет условиям «движение вниз и позиция в нижнем краю» — вызываются оба обработчика, или только один?Могут и два, если у них нет общих переменных, то могу вызваться параллельно, если есть, то друг за другом. Но код в каждом из них будет разный, каждый для своего случая. Это видно на реальном примере. У меня сложностей с пониманием что куда нужно распихивать не возникало ни разу. Но не стану утверждать, что и не возникнет.
Похоже, что так.
Я не про семантически эквивалентный блок, а про процедуру (функцию), как блок.
Это два алгоритма, которые будут реализованы в разных подпрограммах, но вызваны в рамках одного обработчика, который вызывается для ситуации «Транзакция по счету завершилась».
Внутри каждого обработчика можно вызывать друг за другом другие поддпрограммы, или выполнять манипуляции с локальными данными.
Могут и два, если у них нет общих переменных, то могу вызваться параллельно, если есть, то друг за другом.
У меня сложностей с пониманием что куда нужно распихивать не возникало ни разу.
Человек работает с одной, конкретной ситуацией
При программировании человек описывает реакции на входные данные, а не на ситуациюЭто при классическом программировании, не при ситуационном (естественном для человека).
поскольку все ситуации уникальные и все их просто невозможно перечислитьВ программе программист пытается описать все ситуации, иначе кому нужна программа, которая не обрабатывает часть из возможных ситуаций. Обычно в таких неописанных ситуациях программа ведет себя непредсказуемо или вообще падает в дапм (корку). Разве это хорошо?
Когда правила формулирует система в результате диалога с человеком, это какая-то далёкая фантастика, в стиле «ты тут сам подумай, разберись и сделай, чтобы все мои пожелания были учтены».Ничто не заставляет задуматься об этом уже сейчас, хотя описанные подходы строго говоря совсем о другом.
В программе программист пытается описать все ситуации
Да, вы превращаете два уровня вложенности условий в соответствующее количество плоских условий,
тем самым увеличивая их числоЭм…
При этом вы забываете тот занимательный факт, что количество объектов одного уровня, воспринимаемых человеком, ограниченно, а иерархия как раз позволяет снять эту проблему.В этом то и дело, линейные ситуации, для человека не иерархические. Только для системы.
В этом то и дело, линейные ситуации, для человека не иерархические
Объектами кода человек вообще не будет оперировать.
Это неправда. Человеческий мозг прекрасно структурирует информацию — именно для того, чтобы бороться со сложностью, — и иерархия один из способов такого структурирования.Согласен
Банальный пример (из тех же правил): "(в некоторый момент игры) вы взяли карту. Если это карта типа а, то. Если эта карта типа б, то." Мы сначала ограничили область видимости («в некоторый момент игры вы взяли карту»), а только потом разбираем ее тип. Вот и иерархия.Но это можно представить и как линейный список:
Но это можно представить и как линейный список:
Какого контекста? Можете привести пример?Например, человек один раз ввел «Идет игра». И как вы говорили раньше, спустится на один уровень иерархии, далее будет работать только с условиями актуальными только для режима игры. Через коммуникационный интерфейс можно будет запрашивать доступные на текущем уровне иерархии условия, переходить по уровням вниз-вверх.
Это при классическом программировании, не при ситуационном (естественном для человека).
которые вас не красятНу я же не красна девица. Да и вообще могу вам не отвечать, как троллю. Что вобщем-то скоро и случится.
Сейчас эта проблема решена модульностью (подпрограммами).
Но его символическое представление видимо глобально.
(?чего змейки, ?какая текущая) секция ?что является ?чем головой. змейка ?что движется ?куда вниз. змейки ?чего голова ?что находится ?где клетка (?какая *самая нижняя, ?чего поля).
start on tty-added or cua-added
script
...
end script
это просто естественное развитие функций консоли, т.е. неизбежно.
Программные инструкции на естественном языке, или интенциональное программирование