Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Wertetabellen für logische Aussagen (Kleinprojekte)

Schreiben Sie ein Programm, dass einen String entgegennimmt, der einer logischen Aussage entspricht (s. http://de.wikipedia.org/wiki/Aussagenlogik). Dabei sollte die Struktur so aussehen, dass 'nicht' durch ein '-', 'und' durch ein '*' und 'oder' durch ein '+' repräsentiert wird (z.B. '(A*-B)+(-A*B)' bedeutet '(A und nicht B) oder (nicht A und B)' -> Exklusiv-Oder). Weiterhin sollten Variablen durch Großbuchstaben repräsentiert werden und Klammern verneint werden können.

Ihr Programm soll diesen String verstehen und als Ergebnis eine Warheitstabelle für diese Aussage ausgeben. In dieser Warheitstabelle stehen alle Möglichkeiten für die Belegung der Variablen aus der Eingabe und das Ergebnis der Eingabe zu diesen Werten.

Als Tipp für alle, die Python als Programmiersprache nutzen: Es lohnt sich ein Blick auf das pyparsing Modul.

1 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

Kommentare (1)

cravay 11. April 2015 18:44   reply report
Ich glaube beim ersten Beispiel von "Verifikation/Checksumme" sollte es heissen "(A*B)+(-A*-B)".

2 Lösung(en)

'''Dieses Programm nimmt einen String entgegen der in der logischen
Schreibweise geschrieben wurde und gibt dann eine Tabelle aller moeglichen
Faelle zurueck'''

import pyparsing as pyp
from functools import reduce
from itertools import chain
from collections import OrderedDict
from string import ascii_uppercase as LETTERS


def elements_of(list1, list2):
    '''Returns a list containing every elemement of list1 if in list2.'''
    return [e for e in list1 if e in list2]

def flatten(l):
    '''Makes the list l flat.'''
    if isinstance(l, list):
        return reduce(lambda x, y: x+y, map(flatten, l))
    else:
        return [l]

def flatten2d(l):
    '''Makes the 2d-list l flat.'''
    return list(chain.from_iterable(l))

def replace(old, new, l):
    '''Replaces every old in l with new.'''
    return [e if e != old else new for e in l]

def replace_all(replacements, l):
    '''Does multiple replacements in one step.'''
    for o, n in replacements:
        l = replace(o, n, l)
    return l

def get(l, index, default=None):
    '''Like the dict.get, but for lists.'''
    try:
        return l[index]
    except IndexError:
        return default

def sort_dict(d):
    '''Sorts a dict by the keys of the items and returns a OrderedDict'''
    return OrderedDict(sorted(d.items()))

def pretty_matrix(matrix):
    '''Returns a pretty formatted matrix (2d)'''
    column_widths = []
    matrix = [[str(col) for col in row] for row in matrix]
    yxmatrix = list(zip(*matrix))
    for col in yxmatrix:
        column_widths.append(max(len(e) for e in col))
    r = ""
    for i, row in enumerate(matrix):
        for j, col in enumerate(row):
            r += ("{:<"+str(column_widths[j])+"} ").format(col)
        r += "\n"
    return r[:-1]

def join_in_list(l, symbol="|"):
    '''Puts the symbol between every two adjacent elements in l'''
    return flatten2d(zip(l, [symbol]*len(l)))[:-1]

def combinations(l, length=None, _already=[]):
    length = length or len(l)
    if len(_already) >= length:
        yield _already
    else:
        for v in l:
            for y in combinations(l, length, _already+[v]):
                yield y

def print_table(keys, values):
    '''Print a table with keys as keywords and values as possible values'''
    keys = join_in_list(keys)
    values = [join_in_list(line) for line in values]
    text = pretty_matrix([keys]+values)
    lines = text.split("\n")
    lines.insert(1, "-"*(len(lines[0])-1))
    print("\n".join(lines))


expr = pyp.Forward()
variable = pyp.Word(LETTERS, exact=1)
negation = pyp.Optional(pyp.Literal("-"))
operator = pyp.oneOf("* +")
atom = negation&variable | \
      negation&pyp.Group(pyp.Literal("(").suppress()+
                       expr+pyp.Literal(")").suppress())
expr << atom + (operator + atom)*(0,1)

class Statement(object):
    expression = expr #The expression to check the input
    
    @staticmethod
    def parse(string):
        return Statement.expression.parseString(string, True).asList()
            
    @staticmethod
    def _eval(l):
        r = replace_all([("*", "and"), ("+", "or"), ("-", "not")], l)
        r = [e if not isinstance(e, list) else "("+Statement._eval(e)+")"
             for e in r]
        r = " ".join(r)
        return r

    @staticmethod
    def _string(l):
        r = [e if not isinstance(e, list) else "("+Statement._string(e)+")"
             for e in l]
        r = "".join(r)
        return r

    def __init__(self, string):
        try:
            if type(string) != str:
                raise ValueError()
            self.statement = Statement.parse(string)
        except (pyp.ParseBaseException, ValueError):
            raise ValueError("Invalid input string")
        self.variables = sorted(set(variable for variable in
                                    flatten(self.statement)
                                    if variable in LETTERS))

    def __str__(self):
        return Statement._string(self.statement)

    def __repr__(self):
        return 'Aussage("'+str(self)+'")'

    def __eq__(self, other):
        return str(self) == str(other)

    def eval(self):
        return Statement._eval(self.statement)

    def result(self, **kwargs):
        try:
            return bool(eval(self.eval(), kwargs))
        except NameError:
            raise ValueError("Es muessen alle Variablen gesetzt werden.")

    def truth_table(self):
        variable_values = {}
        values = []
        for combi in combinations([0, 1], len(self.variables)):
            variable_values = sort_dict({self.variables[i]:v
                                         for i, v in enumerate(combi)})
            values.append(list(variable_values.values())+
                          [int(self.result(**variable_values))])
        return self.variables+["Ergebnis"], values


print("""Dieses Programm gibt fuer eine logische Verknuepfung von Variablen
in der logischen Schreibweise (s. de.wikipedia.org/wiki/Aussagenlogik) eine
Wahrheitstabelle aus.
Gib eine logische Verknuepfung ein.
Schreibe dabei 'nicht' als vorgestelltes '-', 'und' als '*' und 'oder' als '+'.
Achte darauf, dass nur ein Operator (* oder +) pro Klammer und als Variablen-
namen nur Großbuchstaben erlaubt sind.
funktioniert      : "-(A*-B)" oder "(-A*B)+(A*-B)"
funktioniert nicht: "A*B*C" oder "A oder B"
""")
                 
while True:
    inp = input("logische Aussage: ")
    if inp in ["exit", "quit"]:
        break
    try:
        statement = Statement(inp)
    except ValueError:
        print("Fehlerhafte Eingabe")
        continue
    else:
        print()
        print_table(*statement.truth_table())
        break

                

Lösung von: Karl Welzel ()

// eingabemaske
document.write(
  '<p>Aussage:<br><input type="text" value="(A*-B)+(-A*B)" id="formula"' +
    'onchange="calculate()"></p>' +
  '<table>' +
    '<td>A…Z</td><td>Variable</td>' +
    '</tr><tr>' +
      '<td>-</td><td>logisches <i>nicht</i> (¬)</td>' +
    '</tr><tr>' +
    '<td>*</td><td>logisches <i>und</i> (?)</td>' +
    '</tr><tr>' +
    '<td>+</td><td>logisches <i>oder</i> (?)</td>' +
    '</tr><tr>' +
    '<td>( )</td><td>In-/Exklusionen</td></tr>' +
  '</table>' +
  '<p id="out"></p>'
);

function calculate() {
  var proposition = document.getElementById("formula").value,
      // netterweise übernehmen wir das mit den großbuchstaben
      calculus = proposition.toUpperCase(),
      variables = [],
      values = [],
      out = document.getElementById("out"),
      outTable = "",
      i;

  // setzt die werte ein und liefert das ergebnis
  function evaluate() {
    var temp = calculus;
    for (i = 0; i < values.length; i++) {
      var reg = new RegExp(variables[i], "g");
      temp = temp.replace(reg, values[i]);
    }
    return eval(temp);
  }

  // tabellenzeile schreiben
  function writeTableLine() {
    var i = 0;
    outTable += "<tr>";
    while (i < values.length) {
      outTable +="<td>";
      values[i] == true ? outTable += "w</td>" : outTable += "f</td>";
      i++;
    }
    outTable += "<td>";
    evaluate() == true ? outTable += "w</td></tr>" : outTable += "f</td></tr>";
  }

  // junktoren nach javascript übersetzen
  calculus = calculus.replace(/-/g, "!");       // NOT
  calculus = calculus.replace(/\*/g, "&&");     // AND
  calculus = calculus.replace(/\+/g, "||");     // OR

  // großbuchstaben finden und an $variables übergeben
  for (i = 0; i < calculus.length; i++)
    if (calculus.charCodeAt(i) >= 65 && calculus.charCodeAt(i) <= 90)
      variables.push(calculus[i]);

  // $variables sortieren und dubletten löschen
  variables.sort();
  i = 0;
  while (i < variables.length) {
    if (variables[i] == variables[i + 1]) variables.splice(i + 1, 1);
    else i++;
  }

  // $values füllen, zunächst alle werte auf "wahr"
  for (i = 0; i < variables.length; i++) values[i] = true;

  // $outTable vorbereiten: tabellenkopf
  outTable += '<table><thead><tr>';
  for (i = 0; i < variables.length; i++) outTable += '<th>' + variables[i] +
    '</th>';
  outTable += '<th>' + proposition + '</th></tr></thead>';

  // überprüfung, ob die aussage wohlgeformt ist,
  // ansonsten tabelle fertigstellen
  try {
    writeTableLine();
    while (eval(values.join("||"))) { // bis alle variablen falsch sind
      // permutation von $values
      i = values.length - 1;
      while (!values[i]) i--;
      values[i] = false;
      for (i++; i < values.length; i++) values[i] = true;
      writeTableLine();
    }
  }
  catch(err) {
    out.innerHTML = (err);
  }
  // ausgabe
  out.innerHTML = outTable + "</table>";
}                                                           // lissalanda@gmx.at

                

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

Verifikation/Checksumme:

Eingabe: (A*-B)+(-A*B)

Ausgabe:

A B Ergebnis
0 0 1
0 1 0
1 0 0
1 1 1

 

Eingabe: -N

Ausgabe:

N Ergebnis
0 1
1 0

 

Eingabe: (*B)+C

Ausgabe: Fehlerhafte Eingabe

 

Eingabe: (c+d)

Ausgabe: Fehlerhafte Eingabe

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 1
Schwierigkeit: Schwer
Webcode: dmor-tqw5
Autor: ()

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen