Python :: Aufgabe #309

1 Lösung Lösung öffentlich

Ternäre Logik (Dreiwertige Logik)

Fortgeschrittener - Python von JKooP - 02.12.2020 um 17:20 Uhr
Statt der bekannten Wahrheitswerte TRUE (t) und FALSE (f) gibt es noch einen weiteren Wert: DON’T CARE (x).
Dies wird als Dreiwertige Logik bezeichnet.

für x gilt zusätzlich bei Junktoren zur bekannten Aussagenlogik:

Negation:
NOT x => x

Konjunktion:
t AND x => x
f AND x => f
x AND x => x

Disjunktion:
t OR x => t
f OR x => x
x OR x => x

und darüber hinaus:

Inklusion:
A -> B => (NOT A) OR B

Äquivalenz:
(A <-> B) => (A -> B) AND (B -> A)

Es soll ein Programm erstellt werden, mit dem es möglich ist,
die o.a. ternäre Logik - auch innerhalb von Inklusion und Äquivalenz - abzubilden.
Hier bieten sich zur Lösung des Problems sowohl Methoden bzw. Funktionen,
als auch, wenn es die Programmiersprache zulässt, Operatorüberladungen an.

Beispiele:
t OR (NOT x) == t
NOT(x) OR (NOT(t)) == x
x -> t == t
(x OR f) <-> (x -> (f AND (NOT x))) == x

Viel Spaß

Lösungen:

vote_ok
von felixTheC (1200 Punkte) - 03.01.2021 um 00:03 Uhr
Quellcode ausblenden Python-Code
from typing import Union

from strongtyping.strong_typing import match_class_typing


@match_class_typing
class tbool:
    """
    Negation:
    -x => x

    Konjunktion:
    x & t => x
    x & f => f
    x & x => x

    Disjunktion:
    x | t => t
    x | f => x
    x | x => x

    Inklusion:
    A ^ B

    Äquivalenz:
    A >= B
    """
    _true = 1
    _false = 0
    _xcare = -1

    def __init__(self, x: Union[int, bool]):
        super().__init__()
        self.x = int(x)
        if self.x > self._true:
            self.x = self._true
        if self.x < self._xcare:
            self.x = self._xcare

    def __or__(self, other: 'tbool'):
        if self.x == self._false and other.x == self._xcare:
            return tbool(self._xcare)
        if self.x == self._xcare and other.x == self._xcare:
            return tbool(self._xcare)
        if self.x == self._true and other.x == self._xcare:
            return tbool(self._true)
        if self.x >= self._false and other.x >= self._false:
            return tbool(bool(self.x) | bool(other.x))
        return other | self

    def __and__(self, other: 'tbool'):
        if self.x == self._true and other.x == self._xcare:
            return tbool(self._xcare)
        if self.x == self._xcare and other.x == self._xcare:
            return tbool(self._xcare)
        if self.x == self._false and other.x == self._xcare:
            return tbool(self._false)
        if self.x >= self._false and other.x >= self._false:
            return tbool(bool(self.x) & bool(other.x))
        return other & self

    def __xor__(self, other: 'tbool'):
        return (-self) | other

    def __neg__(self):
        if self.x == self._true:
            return tbool(self._false)
        elif self.x == self._false:
            return tbool(self._true)
        else:
            return tbool(self._xcare)

    def __ge__(self, other: 'tbool'):
        return (self ^ other) & (self ^ other)

    def __eq__(self, other):
        return self.x == other.x

    def __repr__(self):
        switch = {self._xcare: 'No matter',
                  self._false: 'False',
                  self._true: 'True'}
        return switch[self.x]


TRUE = tbool(1)
FALSE = tbool(0)
XCARE = tbool(-1)


def test_logic():
    assert -XCARE == XCARE

    assert (TRUE & XCARE) == XCARE
    assert (TRUE & XCARE) == (XCARE & TRUE)
    assert (FALSE & XCARE) == FALSE
    assert (FALSE & XCARE) == (XCARE & FALSE)
    assert (XCARE & XCARE) == XCARE

    assert (XCARE | TRUE) == TRUE
    assert (XCARE | FALSE) == XCARE
    assert (XCARE | XCARE) == XCARE

    assert (-XCARE | TRUE) == TRUE
    assert (-XCARE | -TRUE) == XCARE

    assert (XCARE ^ TRUE) == TRUE
    assert ((XCARE | FALSE) >= (XCARE ^ (FALSE & (-XCARE)))) == XCARE

    assert (TRUE & FALSE) == FALSE
    assert (TRUE | FALSE) == TRUE

    assert tbool(1) == tbool(True)
    assert TRUE == tbool(True)

    assert tbool(0) == tbool(False)
    assert FALSE == tbool(False)

    assert TRUE == tbool(10)
    assert XCARE == tbool(-100)


if __name__ == '__main__':
    test_logic()