<?php
// Метод Квайна на PHP (Quine method in PHP)
define('R', 4);
define('SR', 16);
$S = array();
$Rez = array();
$Flag = array();
$Y = array();
$FData = null;
// Подготовка массивов
for ($i = 0; $i < SR * 2; $i++) {
$S[$i] = null;
$Rez[$i] = null;
$Flag[$i] = 0;
}
for ($i = 0; $i < SR; $i++)
$Y[$i] = null;
// Функция формирования дизъюнкта
function make_diz($number) {
$res = '';
for ($i = 0; $i < R; $i++)
$res = (($number >> $i) & 0x01) . $res;
return $res;
}
// Функция склеивания
function splice(&$s1, &$s2, $index_s1, $index_s2) {
global $Rez, $Flag, $indexRez;
// кол-во разных
$k = 0;
$n = null;
for ($i = 0; $i < R; $i++)
if ($s1[$i] != $s2[$i]) {
$k++;
$n = $i;
}
switch ($k) {
case 0:
$Rez[$indexRez] = $s1;
$Flag[$index_s1] = $Flag[$index_s2] = 1;
$indexRez++;
break;
case 1:
if ($s1[$n] != '*' && $s2[$n] != '*') {
$Rez[$indexRez] = $s1;
$Rez[$indexRez][$n] = '*';
$Flag[$index_s1] = $Flag[$index_s2] = 1;
$indexRez++;
}
break;
}
}
// Функция проверки на удаление пустого дизъюнкта
function del(&$s) {
$del = false;
$k = 0;
for ($i = 0; $i < R; $i++)
if ($s[$i] == '*')
$k++;
if ($k == R)
$del = true;
return $del;
}
function clear() {
global $S, $Rez, $Flag, $indexRez;
$indexS = 0;
for ($i = 0; $i < SR * 2; $i++) {
$Flag[$i] = 0;
$S[$i] = '';
}
for ($i = 0; $i < $indexRez - 1; $i++)
if ($Flag[$i] == 0)
for ($j = $i + 1; $j < $indexRez; $j++)
if ($Rez[$i] == $Rez[$j])
$Flag[$j] = 1;
for ($i = 0; $i < $indexRez; $i++)
if ($Flag[$i] == 0) {
$S[$indexS] = $Rez[$i];
$indexS++;
}
return $indexS;
}
// Вывод на экран массива Rez
function print_rez($step, $indexS) {
global $S;
echo '<hr/>';
if ($step == 0)
echo '<b>Исходная ДНФ</b><br/>';
else
echo '<b>Шаг номер: ' . $step . '</b><br/>';
echo 'Количество дизьюнктов: ' . $indexS . '<br/>';
for ($i = 0; $i < $indexS; $i++)
echo $S[$i] . '<br/>';
}
$FData = fopen('func.txt', 'r');
// Считать массив Y из файла
for ($i = 0; $i < SR; $i++)
$Y[$i] = fgetc($FData);
fclose($FData);
// Получить массив S
for ($i = 0; $i < SR; $i++)
$S[$i] = make_diz($i);
// Преоразовать S: оставив только те элементы, для которых Y=1. Результата в Rez
$indexRez = 0;
for ($i = 0; $i < SR; $i++)
if ($Y[$i] == '1') {
$Rez[$indexRez] = $S[$i];
$indexRez++;
}
for ($i = 0; $i < SR*2; $i++)
$S[$i] = $Rez[$i];
$indexS = $indexRez;
print_rez(0, $indexS);
// Склеивание
for ($i = 0; $i < R; $i++) {
// подготовка массива Flag под склеивание
$indexRez = 0;
for ($j = 0; $j < SR * 2; $j++) {
$Flag[$j] = 0;
$Rez[$j] = '';
}
// склеивание
for ($j = 0; $j < $indexS - 1; $j++)
for ($k = $j + 1; $k < $indexS; $k++)
splice($S[$j], $S[$k], $j, $k);
// копирование несклеившихся компонент
for ($j = 0; $j < $indexS; $j++)
if ($Flag[$j] == 0) {
$Rez[$indexRez] = $S[$j];
$indexRez++;
}
// удаление одинаковых дизъюнктов
$indexS = clear();
// вывод результата на экран
print_rez($i+1, $indexS);
}
$indexRez = 0;
// Удалить все дизъюнкты вида **...*
for ($i = 0; $i < $indexS; $i++)
if (! del($S[$i])) {
$Rez[$indexRez] = $S[$i];
$indexRez++;
}
print_rez(R+1, $indexRez);
echo '<hr/>';
for ($i = 0; $i < $indexS; $i++) {
echo '(';
for ($j = 0; $j < R; $j++)
if (isset($S[$i][$j]))
if ($S[$i][$j] != '*')
echo ($S[$i][$j] == '0' ? '-' : null) . 'X' . ($j+1);
echo ')';
if ($i != ($indexS - 1))
echo ' V ';
}