bmstu-iu9 / bmstu-iu9/refal-5-lambda

Условия-отрицания

Open
#168 5 comments 0 reactions 1 assignee Claimed by @Mazdaywik View on GitHub
task
Dominant language
C++
Stars
97
Forks
40
PR merge metrics
No merged PRs in 30d

Description

Нужно добавить во входной язык (в оба) условия-отрицания, т.е. условия, в которых сопоставление с образцом **не** должно выполняться.

# Мотивация
Иногда очень не хватает отрицательных условий. Иногда приходится явно перечислять образцы-исключения, дабы отсечь варианты. Иногда приходится писать неуклюжие условия вида `, : False`, потому что по-другому выражать неравенства ещё хуже. Это как удлинение e-переменных справа-налево. Нужно очень редко, но когда нужно — обидно, что его нет.

Другая причина. Оптимизации #122 и #126 могли бы работать с простыми отрицательными условиями — классическими рестрикциями Турчина (`s.1 ≠ X`, `s.1 ≠ s.2`, `e.1 ≠ ε`), например, отсекать недостижимые предложения. Альтернатива — усложнение оптимизаторов для неявного учёта отрицательной информации из предыдущих предложений.

Третья причина. На Рефале-5λ сможет быть выражен результат суперкомпиляции, рестрикции будут записываться при помощи отрицаний.

# Обзор других диалектов
## Рефал Плюс
В Рефале Плюс можно использовать отрицания условия. Синтаксически они выглядят так:
```
ОтрицаниеУсловия = "#" Источник [Хвост]
```
Т.е. отрицается не результат сопоставления с образцом, а неуспех результатного выражения или распутья. Отсутствие неуспеха в источнике приводит к неуспеху хвоста и наоборот.
## Рефал-6
Рефал-6 позволяет в начало любого действия поставить знак `#`, который инвертирует неуспех в нём — неуспех заменяется на пустое выражение, отсутствие неуспеха приводит к неуспеху.

# Предлагаемый синтаксис
## Рефал-5λ
В условиях и присваиваниях можно заменить знак `:` на знак `#` — сопоставление с образцом должно не выполняться:
```
, Res # Pat
= Res # Pat
```
Область видимости переменных в отрицаемом образце ограничена самим этим образцом. Если образец содержит переопределяемые переменные, то значения одноимённых переменных в последующей части предложения не меняются.

Отрицательное присваивание является синтаксическим сахаром. Запись
```
= Res # Pat
```
эквивалентна
```
= : , Res # Pat
```
Т.е. отрицательное присваивание при успешном сопоставлении валит программу.
## Простой Рефал
Синтаксический сахар с отрицательными присваиваниями не нужен. Знак `#` зарезервирован для идентификаторов, поэтому использовать нельзя.

Поэтому отрицательные условия будут выглядеть так:
```
! Res : Pat
```

# Возможная реализация
Обычное условие компилируется в такой код:
```
F {
Pat, ResC : PatC = Res;
. . .
}
```

```
(CmdSentence
сопоставление с Pat
построение
(CmdSentence
сопоставление с 
построение Res
(CmdNextStep)
)
удаление
)
. . .
```

Отрицания будут компилироваться так:
```
F {
Pat, ResN # PatN = Res;
. . .
}
```

```
(CmdSentence
сопоставление с Pat
построение
NEG = FALSE
(CmdSentence
сопоставление с 
NEG = TRUE
)
удаление
if NEG then FAIL
построение Res
)
. . .
```
Т.е. потребуются три новые команды языка сборки и флаг `NEG`. Можно даже обойтись одной командой, используя разные её аргументы.

# Обсуждение в рассылке refal@botik.ru
* https://www.mail-archive.com/refal@botik.ru/msg00318.html
* https://groups.google.com/forum/#!topic/refal/quFAS40OSio

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.