Pull to refresh

Comments 8

Не "вентиль IMPLY", а "импликация". Есть же устоявшийся термин, который широко используется в литературе.

Оказывается, наша таблица истинности функционально полна, то есть при помощи одного этого вентиля можно создавать произвольные схемы.

Это неверно. Множество булевых функций, состоящее из одной только (обратной) импликации, не является функционально полным. Критерий Поста не позволяет. В множестве нет функции, не принадлежащей предполному замкнутому классу функций, сохраняющих единицу.

Не принадлежит этому классу одна из двух функций, которые автор на самом деле дополнительно использует:

Сначала определим константы...

Вместе с константой 0 импликация образует функционально полное множество булевых функций, да.

Пока выглядит как максимально объёмная обфускация кода на произвольном языке с поддержкой плавающей запятой. Полагаю, можно использовать в местах где скорость не важна, но важен результат сокрытия информации.
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+

Чуть более многословно:

#[derive(Clone, Copy)]
pub struct Bit(f32);

impl std::ops::Not for Bit {
    type Output = Self;

    fn not(self) -> Self::Output {
        Self(Self::ZERO.0 - self.0)
    }
}

impl std::ops::BitOr for Bit {
    type Output = Self;

    fn bitor(self, rhs: Self) -> Self::Output {
        Self(self.0 - (!rhs).0)
    }
}

impl std::ops::BitAnd for Bit {
    type Output = Self;

    fn bitand(self, rhs: Self) -> Self::Output {
        !(!self | !rhs)
    }
}

impl std::ops::BitXor for Bit {
    type Output = Self;

    fn bitxor(self, rhs: Self) -> Self::Output {
        (!self & rhs) | (self & !rhs)
    }
}

impl Bit {
    pub const ZERO: Self = Self(-0.0);
    pub const ONE: Self = Self(0.0);

    pub fn adder(a: Self, b: Self, c: Self) -> (Self, Self) {
        let s = a ^ b ^ c;
        let c = ((a ^ b) & c) | (a & b);
        (s, c)
    }
}


pub struct SoftU8 {
    inner: [Bit; 8],
}

impl std::ops::Add for SoftU8 {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        let (s0, c) = Bit::adder(self.inner[0], rhs.inner[0], Bit::ZERO);
        let (s1, c) = Bit::adder(self.inner[1], rhs.inner[1], c);
        let (s2, c) = Bit::adder(self.inner[2], rhs.inner[2], c);
        let (s3, c) = Bit::adder(self.inner[3], rhs.inner[3], c);
        let (s4, c) = Bit::adder(self.inner[4], rhs.inner[4], c);
        let (s5, c) = Bit::adder(self.inner[5], rhs.inner[5], c);
        let (s6, c) = Bit::adder(self.inner[6], rhs.inner[6], c);
        let (s7, _) = Bit::adder(self.inner[7], rhs.inner[7], c);
        Self {
            inner: [s0, s1, s2, s3, s4, s5, s6, s7],
        }
    }
}

impl Into<SoftU8> for u8 {
    fn into(self) -> SoftU8 {
        SoftU8 {
            inner: std::array::from_fn(|i| if (self >> i) & 1 == 1 { Bit::ONE } else { Bit::ZERO }),
        }
    }
}

impl Into<u8> for SoftU8 {
    fn into(self) -> u8 {
        (0..8).filter(|i| self.inner[*i].0.signum() > 0.0).map(|i| 1 << i).sum()
    }
}

fn main() {
    let a: SoftU8 = 23.into();
    let b: SoftU8 = 19.into();
    let c = a + b;
    let c: u8 = c.into();
    println!("{}", c);
}

Соответственно:

f_xor = lambda a,b: f_or(f_not(a-b), f_not(b-a))

Это шуточный пост?
Помнится в универе, да и здесь, на Хабре, в давние, травазеленистее времена было обсуждение про функциональную полность СЛОЖЕНИЯ.
Если сложение полное, то ведь и ребенку ясно что выитание, то бишь сложение отрицательных выражении, так же функционально полное.

Sign up to leave a comment.

Articles