// 2025-2026 Богданович Давид Когут Прихожденко (кдб.дійсність.укр)

взяти визначення мавка/машина;
взяти визначення КД;

простір мавка {
  дія здійснити(
    М: адреса<Машина>,
    здійснювач: Значення,
    значення: Значення,
    задіяні: Задіяні,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо значення.вид == ЗНедійсне {
      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо здійснити \"недійсне\"."), місцезнаходження);
    }

    якщо значення.вид == ЗДійсне {
      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо здійснити \"дійсне\"."), місцезнаходження);
    }

    якщо значення.вид == ЗЧисло {
      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо здійснити число."), місцезнаходження);
    }

    змінна предмет = значення.дані як адреса<Предмет>;

    якщо предмет.клас == М.клас_Дія {
      вернути предмет_дії_здійснити(
        М,
        здійснювач,
        предмет як адреса<ПредметДії>,
        задіяні,
        місцезнаходження
      );
    }

    якщо предмет.клас == М.клас_Клас {
      вернути клас_здійснити(
        М,
        предмет як адреса<ПредметКласу>,
        задіяні,
        місцезнаходження
      );
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо здійснити предмет."), місцезнаходження);
  }

  // позначка: прохід по типах предметів
  дія отримати_властивість(
    М: адреса<Машина>,
    значення: Значення,
    назва: адреса<ПредметТексту>,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо значення.вид == ЗНедійсне {
      змінна накопичувач_тексту = зробити_накопичувач_тексту(М, 50);
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, "Неможливо отримати властивість \"");
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, назва.значення);
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, "\" недійсного.");
      вернути МІСЦЕПАДІННЯ(М, створити_текст_без_копіювання(М, накопичувач_тексту.розмір, накопичувач_тексту.дані), місцезнаходження);
    }

    якщо значення.вид == ЗДійсне {
      вернути НЕДІЙСНЕ;
    }

    якщо значення.вид == ЗЧисло {
      вернути НЕДІЙСНЕ;
    }

    змінна предмет = значення.дані як адреса<Предмет>;

    якщо предмет.клас.вбудований {
      якщо предмет.клас == М.клас_Клас {
        вернути клас_отримати_властивість(
          М,
          предмет як адреса<ПредметКласу>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Дані {
        вернути предмет_даних_отримати_властивість(
          М,
          предмет як адреса<ПредметДаних>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_ДіапазонЧисел {
        вернути предмет_діапазону_чисел_отримати_властивість(
          М,
          предмет як адреса<ПредметДіапазонуЧисел>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Дія {
        вернути предмет_дії_отримати_властивість(
          М,
          предмет як адреса<ПредметДії>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Код {
        вернути предмет_коду_отримати_властивість(
          М,
          предмет як адреса<ПредметКоду>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Модуль {
        вернути предмет_модуля_отримати_властивість(
          М,
          предмет як адреса<ПредметМодуля>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Параметр {
        вернути предмет_параметра_отримати_властивість(
          М,
          предмет як адреса<ПредметПараметра>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_ПеребірДаних {
        вернути предмет_перебору_даних_отримати_властивість(
          М,
          предмет як адреса<ПредметПереборуДаних>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_ПеребірДіапазонуЧисел {
        вернути предмет_перебору_діапазону_чисел_отримати_властивість(
          М,
          предмет як адреса<ПредметПереборуДіапазонуЧисел>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_ПеребірПослідовності {
        вернути предмет_перебору_послідовності_отримати_властивість(
          М,
          предмет як адреса<ПредметПереборуПослідовності>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_ПеребірСловника {
        вернути предмет_перебору_словника_отримати_властивість(
          М,
          предмет як адреса<ПредметПереборуСловника>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_ПеребірСписку {
        вернути предмет_перебору_списку_отримати_властивість(
          М,
          предмет як адреса<ПредметПереборуСписку>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_ПеребірТексту {
        вернути предмет_перебору_тексту_отримати_властивість(
          М,
          предмет як адреса<ПредметПереборуТексту>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Послідовність {
        вернути предмет_послідовності_отримати_властивість(
          М,
          предмет як адреса<ПредметПослідовності>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Словник {
        вернути предмет_словника_отримати_властивість(
          М,
          предмет як адреса<ПредметСловника>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Список {
        вернути предмет_списку_отримати_властивість(
          М,
          предмет як адреса<ПредметСписку>,
          назва,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Текст {
        вернути предмет_тексту_отримати_властивість(
          М,
          предмет як адреса<ПредметТексту>,
          назва,
          місцезнаходження
        );
      }

      змінна накопичувач_тексту = зробити_накопичувач_тексту(М, 50);
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, "Неможливо отримати властивість \"");
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, назва.значення);
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, "\" предмета.");
      вернути МІСЦЕПАДІННЯ(М, створити_текст_без_копіювання(М, накопичувач_тексту.розмір, накопичувач_тексту.дані), місцезнаходження);
    }

    вернути складений_предмет_отримати_властивість(
      М,
      значення.дані як адреса<Предмет> як адреса<СкладенийПредмет>,
      назва,
      місцезнаходження
    );
  }

  // позначка: прохід по типах предметів
  дія змінити_властивість(
    М: адреса<Машина>,
    значення: Значення,
    назва: адреса<ПредметТексту>,
    значення_властивості: Значення,
    місцезнаходження: Місцезнаходження
  ) -> СтанПадіння {
    якщо значення.вид == ЗНедійсне {
      МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо змінити властивість недійсного."), місцезнаходження);
      вернути;
    }

    якщо значення.вид == ЗДійсне {
      МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо змінити властивість дійсного."), місцезнаходження);
      вернути;
    }

    якщо значення.вид == ЗЧисло {
      МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо змінити властивість числа."), місцезнаходження);
      вернути;
    }

    змінна предмет = значення.дані як адреса<Предмет>;

    якщо предмет.клас.вбудований {
      якщо предмет.клас == М.клас_Клас {
        клас_змінити_властивість(
          М,
          предмет як адреса<ПредметКласу>,
          назва,
          значення_властивості,
          місцезнаходження
        );
        вернути;
      }

      МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо змінити властивість вбудованого предмета."), місцезнаходження);
      вернути;
    }

    складений_предмет_змінити_властивість(
      М,
      значення.дані як адреса<Предмет> як адреса<СкладенийПредмет>,
      назва,
      значення_властивості,
      місцезнаходження
    );
  }

  дія здійснити_властивість(
    М: адреса<Машина>,
    значення: Значення,
    назва: адреса<ПредметТексту>,
    задіяні: Задіяні,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    змінна значення_властивості = отримати_властивість(
      М,
      значення,
      назва,
      місцезнаходження
    );

    якщо М.стан_падіння {
      звільнити_задіяні(М, задіяні);

      вернути НЕДІЙСНЕ;
    }

    якщо значення_властивості.вид == ЗНедійсне {
      звільнити_задіяні(М, задіяні);

      змінна накопичувач_тексту = зробити_накопичувач_тексту(М, 50);
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, "Неможливо здійснити недійсне (властивість \"");
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, назва.значення);
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, "\").");

      вернути МІСЦЕПАДІННЯ(М, створити_текст_без_копіювання(М, накопичувач_тексту.розмір, накопичувач_тексту.дані), місцезнаходження);
    }

    вернути здійснити(
      М,
      значення,
      значення_властивості,
      задіяні,
      місцезнаходження
    );
  }

  // позначка: прохід по типах предметів
  дія отримати_елемент(
    М: адреса<Машина>,
    значення: Значення,
    ключ: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо значення.вид == ЗПредмет {
      змінна предмет = значення.дані як адреса<Предмет>;

      якщо предмет.клас == М.клас_Дані {
        вернути предмет_даних_отримати_елемент(
          М,
          предмет як адреса<ПредметДаних>,
          ключ,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Послідовність {
        вернути предмет_послідовності_отримати_елемент(
          М,
          предмет як адреса<ПредметПослідовності>,
          ключ,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Словник {
        вернути предмет_словника_отримати_елемент(
          М,
          предмет як адреса<ПредметСловника>,
          ключ,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Список {
        вернути предмет_списку_отримати_елемент(
          М,
          предмет як адреса<ПредметСписку>,
          ключ,
          місцезнаходження
        );
      }

      якщо предмет.клас == М.клас_Текст {
        вернути предмет_тексту_отримати_елемент(
          М,
          предмет як адреса<ПредметТексту>,
          ключ,
          місцезнаходження
        );
      }
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо отримати елемент з цього типу предмета."), місцезнаходження);
  }

  // позначка: прохід по типах предметів
  дія змінити_елемент(
    М: адреса<Машина>,
    значення: Значення,
    ключ: Значення,
    значення_елемента: Значення,
    місцезнаходження: Місцезнаходження
  ) -> СтанПадіння {
    якщо значення.вид == ЗНедійсне {
      МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо змінити елемент недійсного."), місцезнаходження);
      вернути;
    }

    якщо значення.вид == ЗДійсне {
      МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо змінити елемент дійсного."), місцезнаходження);
      вернути;
    }

    якщо значення.вид == ЗЧисло {
      МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо змінити елемент числа."), місцезнаходження);
      вернути;
    }

    змінна предмет = значення.дані як адреса<Предмет>;

    якщо предмет.клас == М.клас_Дані {
      предмет_даних_змінити_елемент(
        М,
        предмет як адреса<ПредметДаних>,
        ключ,
        значення_елемента,
        місцезнаходження
      );
      вернути;
    }

    якщо предмет.клас == М.клас_Словник {
      предмет_словника_змінити_елемент(
        М,
        предмет як адреса<ПредметСловника>,
        ключ,
        значення_елемента,
        місцезнаходження
      );
      вернути;
    }

    якщо предмет.клас == М.клас_Список {
      предмет_списку_змінити_елемент(
        М,
        предмет як адреса<ПредметСписку>,
        ключ,
        значення_елемента,
        місцезнаходження
      );
      вернути;
    }
  }

  // позначка: прохід по типах предметів
  дія отримати_текст(
    М: адреса<Машина>,
    значення: Значення,
    місцезнаходження: Місцезнаходження
  ) -> адреса<ПредметТексту> {
    якщо значення.вид == ЗНедійсне {
      вернути М.константи_назв._недійсне;
    }

    якщо значення.вид == ЗДійсне {
      вернути М.константи_назв._дійсне;
    }

    якщо значення.вид == ЗЧисло {
      змінна значення_кд: кд;

      якщо перетворити_р64_в_кд(М, значення.дані як р64, значення_кд::адреса) {
        вернути створити_текст_без_копіювання(М, значення_кд.розмір, значення_кд.дані);
      }

      МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалось перетворити число в текст."), місцезнаходження);
      вернути пусто;
    }

    змінна предмет = значення.дані як адреса<Предмет>;

    якщо предмет.клас == М.клас_Текст {
      вернути предмет як адреса<ПредметТексту>;
    }

    змінна результат = здійснити_властивість(
      М,
      значення,
      М.константи_назв._чародія_текст,
      Задіяні { 0, пусто, 0, пусто },
      місцезнаходження
    );

    якщо М.стан_падіння {
      вернути пусто;
    }

    якщо результат.вид != ЗПредмет {
      МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалось перетворити в текст."), місцезнаходження);
      вернути пусто;
    }

    змінна предмет_результату = результат.дані як адреса<Предмет>;

    якщо предмет_результату.клас != М.клас_Текст {
      МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалось перетворити в текст."), місцезнаходження);
      вернути пусто;
    }

    вернути предмет_результату як адреса<ПредметТексту>;
  }

  // позначка: прохід по типах предметів
  дія отримати_діапазон(
    М: адреса<Машина>,
    від: Значення,
    до: Значення,
    включно: логічне,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо від.вид == ЗЧисло {
      якщо до.вид == ЗЧисло {
        вернути ПРЕДМЕТ(створити_діапазон_чисел(
          М,
          від.дані як р64,
          до.дані як р64,
          включно
        ));
      }

      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Неможливо створити діапазон (до не є Число)."), місцезнаходження);
    }

    змінна задіяні = Задіяні { 2, виділити<Значення>(М, 2), 0, пусто };
    задіяні.дані[0] = до;
    якщо включно {
      задіяні.дані[1] = ДІЙСНЕ;
    } інакше {
      задіяні.дані[1] = НЕДІЙСНЕ;
    }

    вернути здійснити_властивість(
      М,
      від,
      М.константи_назв._чародія_діапазон,
      задіяні,
      місцезнаходження
    );
  }

  // позначка: прохід по типах предметів
  дія отримати_перебір(
    М: адреса<Машина>,
    значення: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо значення.вид == ЗПредмет {
      змінна предмет = значення.дані як адреса<Предмет>;

      якщо предмет.клас == М.клас_Дані {
        вернути ПРЕДМЕТ(створити_перебір_даних(
          М,
          предмет як адреса<ПредметДаних>
        ));
      }

      якщо предмет.клас == М.клас_ДіапазонЧисел {
        вернути ПРЕДМЕТ(створити_перебір_діапазону_чисел(
          М,
          предмет як адреса<ПредметДіапазонуЧисел>
        ));
      }

      якщо предмет.клас == М.клас_Послідовність {
        вернути ПРЕДМЕТ(створити_перебір_послідовності(
          М,
          предмет як адреса<ПредметПослідовності>
        ));
      }

      якщо предмет.клас == М.клас_Словник {
        вернути ПРЕДМЕТ(створити_перебір_словника(
          М,
          предмет як адреса<ПредметСловника>
        ));
      }

      якщо предмет.клас == М.клас_Список {
        вернути ПРЕДМЕТ(створити_перебір_списку(
          М,
          предмет як адреса<ПредметСписку>
        ));
      }

      якщо предмет.клас == М.клас_Текст {
        вернути ПРЕДМЕТ(створити_перебір_тексту(
          М,
          предмет як адреса<ПредметТексту>
        ));
      }
    }

    вернути здійснити_властивість(
      М,
      значення,
      М.константи_назв._чародія_перебір,
      Задіяні { 0, пусто, 0, пусто },
      місцезнаходження
    );
  }

  дія виконати_додати(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_додати(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати додавання можна лише між числами."), місцезнаходження);
  }

  дія виконати_відняти(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_відняти(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати віднімання можна лише між числами."), місцезнаходження);
  }

  дія виконати_помножити(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_помножити(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати множення можна лише між числами."), місцезнаходження);
  }

  дія виконати_поділити(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_поділити(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати ділення можна лише між числами."), місцезнаходження);
  }

  дія виконати_остача(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_остача(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати остачу можна лише між числами."), місцезнаходження);
  }

  дія виконати_степінь(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_степінь(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати піднесення до степеня можна лише між числами."), місцезнаходження);
  }

  дія виконати_вліво(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_вліво(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати двійкове зсув вліво можна лише між числами."), місцезнаходження);
  }

  дія виконати_вправо(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_вправо(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати двійкове зсув вправо можна лише між числами."), місцезнаходження);
  }

  дія виконати_двійкове_і(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_двійкове_і(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати двійкове І можна лише між числами."), місцезнаходження);
  }

  дія виконати_двійкове_або(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_двійкове_або(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати двійкове АБО можна лише між числами."), місцезнаходження);
  }

  дія виконати_двійкове_вабо(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_двійкове_вабо(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати двійкове ВАБО можна лише між числами."), місцезнаходження);
  }

  дія виконати_менше(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_менше(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати перевірку чи менше можна лише між числами."), місцезнаходження);
  }

  дія виконати_більше(
    М: адреса<Машина>,
    ліво: Значення,
    право: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо ліво.вид == ЗЧисло {
      вернути предмет_числа_більше(М, ліво.дані як р64, право, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати перевірку чи більше можна лише між числами."), місцезнаходження);
  }

  дія виконати_двійкове_не(
    М: адреса<Машина>,
    значення: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо значення.вид == ЗЧисло {
      вернути предмет_числа_двійкове_не(М, значення.дані як р64, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати двійкове НЕ можна лише для чисел."), місцезнаходження);
  }

  дія виконати_змінити_знак(
    М: адреса<Машина>,
    значення: Значення,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    якщо значення.вид == ЗЧисло {
      вернути предмет_числа_змінити_знак(М, значення.дані як р64, місцезнаходження);
    }

    вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Виконати зміну знаку можна лише для чисел."), місцезнаходження);
  }

  внутрішня дія є_невизначеність(значення: р64) -> логічне {
    вернути значення != значення;
  }

  дія перевірити_чи_значення_рівні(
    М: адреса<Машина>,
    а: Значення,
    б: Значення
  ) -> логічне {
    якщо а.вид != б.вид {
      вернути ні;
    }

    якщо а.вид == ЗНедійсне {
      вернути так;
    }

    якщо а.вид == ЗДійсне {
      вернути так;
    }

    якщо а.вид == ЗЧисло {
      якщо є_невизначеність(а.дані як р64) і є_невизначеність(б.дані як р64) {
        вернути ні;
      }

      вернути (а.дані як р64) == (б.дані як р64);
    }

    якщо а.вид != ЗПредмет {
      ЗАПАНІКУВАТИ(М, "Невідомий вид значення у перевірці на рівність.");
    }

    змінна а_предмет = а.дані як адреса<Предмет>;
    змінна б_предмет = б.дані як адреса<Предмет>;

    якщо а_предмет.клас == б_предмет.клас {
      якщо а_предмет.клас == М.клас_Текст {
        вернути перевірити_чи_предмети_тексту_рівні(
          М,
          а_предмет як адреса<ПредметТексту>,
          б_предмет як адреса<ПредметТексту>
        );
      }

      вернути ні;
    }

    вернути ні;
  }

  дія перевірити_чи_предмет_є(
    М: адреса<Машина>,
    а: адреса<Предмет>,
    б: адреса<ПредметКласу>
  ) -> логічне {
    вернути а.клас == б;
  }
}