Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Dreiwertige Logik (Kleinprojekte)

Die allermeisten Programmiersprachen stellen Boole?sche Variablen und Operatoren zu deren Verknüpfung zur Verfügung. Eine Boole?sche Variable ist binär, also 1 oder 0, true oder false.


Die gängigen Operatoren sind:

 

  • Negation (logisches »Nicht«; NOT oder !), 
  • Konjunktion (logisches »Und«; AND oder &&), 
  • Disjunktion (logisches »Oder«; OR oder ||).

 

Die klassische Aussagenlogik kennt darüber hinaus

  • Inklusion (»wenn… dann«) und die 
  • Äquivalenz (»wenn und nur wenn… dann…«).

 

Dabei gilt:

 

Für die Inklusion (A → B):

(A → B) == ((NOT A) or B)


Für die Äquivalenz A ↔ B:

(A ↔ B) == (A → B) AND (B → A)


Andere Modelle der Logik benutzen, neben falsch oder wahr, einen dritten Wahrheitswert, nämlich »unbestimmt«, »nicht bekannt«, »unklar«; oder, näher an der Boole?schen Algebra: ½.


Für diesen dritten Wahrheitswert (hier dark) gilt:


(NOT dark) == dark


true AND dark == dark

false AND dark == false

dark AND dark == dark


true OR dark == true

false OR dark == dark

dark OR dark == dark


Ihre Aufgabe:

Legen Sie eine kleine Programmbibliothek an, die Ausdrücke einer dreiwertigen Logik berechnen kann. Definieren Sie die Grundoperationen NOT, AND, OR für die binären und den dritten Wahrheitswert und leiten Sie Inklusion und Äquivalenz von diesen ab.

Sie müssen hierfür keinen Parser für Ausdrücke bauen. Verschachtelbare Funktionen/Subroutinen reichen vollkommen aus.

Außerdem können Sie frei über Ausdrücke ihrer Programmiersprache verfügen, falls vorhanden. Auch die benutzten Begriffe dienen allein der Anschauung und sind nicht 1:1 umzusetzen. Die Begrifflichkeit unterliegt allein ihrem Planmodell und ihrer Kreativität.

0 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

6 Lösung(en)

# frozen-string-literal: false

$dark = 'dark'

def tfd_and(a, b)
  return false if a == false || b == false

  $dark
end

def tfd_or(a, b)
  return true if a == true || b == true
  
  $dark
end

def tfd_not(a)
  return true if a == false

  return false if a == true

  $dark
end

def tfd_incl(a, b)
  tfd_or(tfd_not(a), b)
end

def tfd_equi(a, b)
  tfd_and(tfd_incl(a, b), tfd_incl(b, a))
end

# Verifikation / Checksumme:

puts 'w or (not u):'
puts tfd_or(true, tfd_not($dark))

puts 'u -> w:'
puts tfd_incl($dark, true)

puts '(u or f) ? (u ? (f and (not u))):'
puts tfd_equi(tfd_or($dark, false), tfd_incl($dark, tfd_and(false, tfd_not($dark))))

                

Lösung von: Ich Bins (tubs)

// NET Core 3.x; C# 8.x

using System;

namespace CS_MDL_CORE_Dreiwertige_Logik
{
    enum Bool
    {
        False, True, Dark
    }

    class Program
    {
        static void Main(string[] args)
        {
            var w = Bool.True;
            var f = Bool.False;
            var u = Bool.Dark;

            Console.WriteLine(OR(w, NOT(u))); // w OR (NOT u) |> True
            Console.WriteLine(INCL(u, w)); // u -> w |> True
            Console.WriteLine(EQUI(OR(u, f), INCL(u, AND(f, NOT(u))))); // (u OR f) <-> (u -> (f AND (NOT u))) |> Dark
        }

        static Bool AND(Bool a, Bool b) => (a, b) switch
        {
            _ when a == Bool.False || b == Bool.False => Bool.False,
            _ when a == Bool.True && b == Bool.True => Bool.True,
            _ => Bool.Dark
        };

        static Bool OR(Bool a, Bool b) => (a, b) switch
        {
            _ when a == Bool.True || b == Bool.True => Bool.True,
            _ when a == Bool.False && b == Bool.False => Bool.False,
            _ => Bool.Dark
        };

        static Bool NOT(Bool a) => a switch { Bool.True => Bool.False, Bool.False => Bool.True, _ => Bool.Dark };
        static Bool INCL(Bool a, Bool b) => OR(NOT(a), b);
        static Bool EQUI(Bool a, Bool b) => AND(INCL(a, b), INCL(b, a));
    }
}
                

Lösung von: Jens Kelm (@JKooP)

// NET Core 3.x
// Achtung: F#

open System

 type Bool =
 |False = 0
 |True = 1
 |Dark = 2

let AND a b = if (a = Bool.False || b = Bool.False) then Bool.False else Bool.Dark
let OR a b = if (a = Bool.True || b = Bool.True) then Bool.True else Bool.Dark
let NOT a = match a with |Bool.True -> Bool.False |Bool.False -> Bool.True |_ -> Bool.Dark
let INCL a b = OR (NOT a) b
let EQUI a b = AND (INCL a b) (INCL b a)

[<EntryPoint>]
let main argv =
    let w = Bool.True
    let f = Bool.False
    let u = Bool.Dark
    printfn "%A" (OR w (NOT u))
    printfn "%A" (INCL u w)
    printfn "%A" (EQUI (OR u f) (INCL u (AND f (NOT u))))
    0
                

Lösung von: Jens Kelm (@JKooP)

// NET Core 3.x; C# 8.x
// Lösung mittels Operatorüberladung

using System;

namespace CS_MDL_CORE_Dreiwertige_Logic_Operatorueberladung
{
    enum Bool
    {
        True, False, Dark
    }

    class Program
    {
        static void Main(string[] args)
        {
            var w = new Logic(Bool.True);
            var f = new Logic(Bool.False);
            var u = new Logic(Bool.Dark);

            // w OR (NOT u) |> True
            Console.WriteLine(w | !u);

            // u -> w |> True
            Console.WriteLine(u != w);

            // (u OR f) <-> (u -> (f AND (NOT u))) |> Dark
            Console.WriteLine(u | f == u != f & !u);
        }
    }

    class Logic
    {
        public Logic(Bool x) => X = x;
        private Bool X { get; }
        public override string ToString() => X.ToString();
        public override bool Equals(object obj) => obj is Logic logic && X == logic.X;
        public override int GetHashCode() => HashCode.Combine(X);
        public static Logic operator &(Logic a, Logic b) => (a, b) switch
        {
            _ when a.X == Bool.False || b.X == Bool.False => new Logic(Bool.False),
            _ when a.X == Bool.True && b.X == Bool.True => new Logic(Bool.True),
            _ => new Logic(Bool.Dark)
        };
        public static Logic operator |(Logic a, Logic b) => (a, b) switch
        {
            _ when a.X == Bool.True || b.X == Bool.True => new Logic(Bool.True),
            _ when a.X == Bool.False && b.X == Bool.False => new Logic(Bool.False),
            _ => new Logic(Bool.Dark)
        };
        public static Logic operator !(Logic a) => a.X switch
        { 
            Bool.True => new Logic(Bool.False),
            Bool.False => new Logic(Bool.True),
            _ => new Logic(Bool.Dark)
        };
        public static Logic operator !=(Logic a, Logic b) => !a | b; // Inklusion (a -> b)
        public static Logic operator ==(Logic a, Logic b) => a != b & b != a; // Äquivalenz (a <-> b)
    }
}

                

Lösung von: Jens Kelm (@JKooP)

/********************************************************\
| In javaScript gibt es den primitiven wert *undefined*, |
| der sich nützlicherweise in kombination mit boolean-   |
| variablen wie gewünscht verhält. Naja, fast.           |
| Hier der test:                                         |
|========================================================|
| AND:                                                   |
|    true      && undefined  // undefined   :-)          |
|    false     && undefined  // false       :-)          |
|    undefined && undefined  // undefined   :-)          |
|                                                        |
| OR:                                                    |
|    true      || undefined  // true        :-)          |
|                                                        |
|    false     || undefined  // undefined   :-) ABER:    |
|    undefined || false      // false       %-(          |
|                                                        |
|    undefined || undefined  // undefined   :-)          |
|                                                        |
| NOT:                                                   |
|    !undefined              // true        :-(          |
|========================================================|
| Das kann uns tatsächlich einige typtests               |
| ersparen, zumindest was AND angeht.                    |
|                                                        |
| /!\ WARNUNG: NSFW! /!\                                 |
| Das willkürliche manipulieren und die unkontrollierte  |
| übernahme von *undefined* in funktionen kann in        |
| komplexeren systemen saarlandgroße löcher ins          |
| programmiererknie schießen.                            |
| Aber hier, als demonstration, funktioniert es erstmal  |
| hinlänglich.                                           |
\********************************************************/

let L3 = {

  not: function(a) {
    return typeof a == 'boolean' ? !a : undefined; // s. o.
  },

  and: function(a, b) { return a && b; },

  // hier der spielverderber (s. o.)
  or: function(a, b) {
    if (a == true || b == true) return true;
    if (a == false && b == false) return false;
    return undefined;
  },

  // implikation
  if: function(a, b) {
    return this.or(this.not(a), b);
  },

  // äquivalenz
  iff: function(a, b) {
    return this.and(this.if(a, b), this.if(b, a));
  }
};

// ausgabe
let w = true, f = false, u = undefined;

// w OR (NOT u)
console.log( L3.or(w, L3.not(u)) );

// u -> w
console.log( L3.if(u, w) );

// (u OR f) <=> (u -> [f AND {NOT u}])
console.log(
  L3.iff(L3.or(u, f), L3.if(u, L3.and(f, L3.not(u))))
);                                      // lissalanda@gmx.at

                

Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)

// C++ 11

// main

#include "Logic.h"
#include <iostream>
#include <string>
using namespace std;

int main()
{
	auto w{ Logic(Bool::True) };
	auto f{ Logic(Bool::False) };
	auto u{ Logic(Bool::Dark) };

	// w OR (NOT u) |> True
	cout << (w | !u) << endl;

	// u -> w | > True
	cout << (u != w) << endl;

	// (u OR f) <-> (u -> (f AND (NOT u))) |> Dark
	cout << (u | f == u != f & !u) << endl;
}


// Logic.h

#pragma once
#include <ostream>
using namespace std;

enum class Bool
{
    True, False, Dark
};

class Logic
{
private:
    Bool X;
public:
    Logic(Bool x) { X = x; };
    friend Logic operator&(Logic const&, Logic const&);
    friend Logic operator|(Logic const&, Logic const&);
    friend Logic operator!(Logic const&);
    friend Logic operator!=(Logic const&, Logic const&);
    friend Logic operator==(Logic const&, Logic const&);
    friend ostream& operator<<(ostream&, Logic const&);
};

// Logic.cpp

#include "Logic.h"

string get_bool(Bool b) {
	switch (b) {
	case Bool::True: return "True"; break;
	case Bool::False: return "False"; break;
	default: return "Dark";
	}
}

Logic operator&(Logic const& a, Logic const& b) {
	if (a.X == Bool::False || b.X == Bool::False) return Logic(Bool::False);
	else if (a.X == Bool::True && b.X == Bool::True) return Logic(Bool::True);
	else return Logic(Bool::Dark);
}

Logic operator|(Logic const& a, Logic const& b) {
	if (a.X == Bool::True|| b.X == Bool::True) return Logic(Bool::True);
	else if (a.X == Bool::False && b.X == Bool::False) return Logic(Bool::False);
	else return Logic(Bool::Dark);
}

Logic operator!(Logic const& a) {
	switch (a.X) {
		case Bool::True: return Logic(Bool::False);
		case Bool::False: return Logic(Bool::True);
		default: return Logic(Bool::Dark);
	}
}

Logic operator!=(Logic const& a, Logic const& b) {
	return Logic(!a | b);
}

Logic operator==(Logic const& a, Logic const& b) {
	return Logic(a != b & b != a);
}

ostream& operator<<(ostream& o, Logic const& v) {
	return o << get_bool(v.X);
}
                

Lösung von: Jens Kelm (@JKooP)

Verifikation/Checksumme:

w := true;
f := false;
u := dark;

w OR (NOT u)
(== true)

u → w
(== true)

(u OR f) ↔ (u → (f AND (NOT u)))
(== dark)

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 1.5
Schwierigkeit: Mittel
Webcode: ah6v-uj4h
Autor: ()

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen