<jupyter_start><jupyter_text>The Visit A part of the Smith family is visiting the Walton family.  Oberstgruppenführer <NAME> has three children with his wife Helen.  His oldest child is a boy called Thomas.  Thomas has two sisters that are called Amy and Jennifer, respectively.  Jennifer is the youngest child.  The following facts are known:    If Mr. Smith is going, he will take his wife Helen along.    At least one of the two older children will visit the Waltons.    Either Mrs. Smith or Jennifer will visit the Waltons.    Either the two daughters will visit the Waltons together or neither of them will         visit the Waltons.    If Thomas visits the Waltons, both Mr. Smith and Amy will also visit the         Waltons.What part of the Smith family will visit the Walton family? Define the set $P$ of propositional variables:<jupyter_code>P = { 'jo', 'he', 'th', 'am', 'je' }<jupyter_output><empty_output><jupyter_text>Your next task is to translate the facts given above into formulas from propositional logic.  If Mr. Smith is going, he will take his wife Helen along:<jupyter_code>f1 = 'jo → he'<jupyter_output><empty_output><jupyter_text>At least one of the two older children will visit the Waltons:<jupyter_code>f2 = 'th ∨ am'<jupyter_output><empty_output><jupyter_text>Either Mrs. Smith or Jennifer will visit the Waltons:<jupyter_code>f3 = '(he ∨ je) ∧ ¬(he ∧ je)'<jupyter_output><empty_output><jupyter_text>Either the two daughters will visit the Waltons together or neither of them will visit the Waltons:<jupyter_code>f4 = '(am ∧ je) ∨ ¬(am ∨ je)'<jupyter_output><empty_output><jupyter_text>If Thomas visits the Waltons, both Mr. Smith and Amy will also visit the Waltons:<jupyter_code>f5 = 'th → jo ∧ am'<jupyter_output><empty_output><jupyter_text>We define the set $\texttt{Fs}$ of all formulas:<jupyter_code>Fs = { f1, f2, f3, f4, f5 }<jupyter_output><empty_output><jupyter_text>We need to transform the strings f1 to f5 into nested tuples representing formulas.  To this end we import a parser for propositional formulas.<jupyter_code>import propLogParser as plp

def transform(s):
    "transform the string s into a nested tuple"
    return plp.LogicParser(s).parse()<jupyter_output><empty_output><jupyter_text>Next, we transform all formulas into nested tuples:<jupyter_code>Fs = { transform(f) for f in Fs }
Fs<jupyter_output><empty_output><jupyter_text>We are looking for a variable assignment $\mathcal{I}$ that satisfies all formulas in the set Fs.  As variable assignments are represented as subsets of the set $\mathcal{P}$ of propositional variables, we can just iterate of all subsets of $\mathcal{P}$. We have previously discussed how to compute the power set $2^M$ of a given set $M$:<jupyter_code>def power(M):
    "This function computes the power set of the set M."
    if M == set():
        return { frozenset() }
    else:
        C  = set(M)  # C is a copy of M as we don't want to change the set M
        x  = C.pop() # pop removes some element x from the set C
        P1 = power(C)
        P2 = { A | {x} for A in P1 }
        return P1 | P2<jupyter_output><empty_output><jupyter_text>The function $\texttt{evaluate}(F, I)$ takes a propositional formula $F$ and a propositional variable assignment $I$ and evaluates $F$ using the assignment $I$.  We have discussed the details of this function previously.<jupyter_code>def evaluate(F, I):
    "Evaluate the propositional formula F using the interpretation I"
    if isinstance(F, str):       # F is a propositional variable
        return F in I            # This variable is true if it occurs in I
    if F[0] == '⊤': return True
    if F[0] == '⊥': return False
    if F[0] == '¬': return not evaluate(F[1], I)
    if F[0] == '∧': return evaluate(F[1], I) and evaluate(F[2], I)
    if F[0] == '∨': return evaluate(F[1], I) or evaluate(F[2], I)
    if F[0] == '→': return not evaluate(F[1], I) or evaluate(F[2], I)
    if F[0] == '↔': return evaluate(F[1], I) == evaluate(F[2], I)<jupyter_output><empty_output><jupyter_text>The function $\texttt{allTrue}(\texttt{Fs}, I)$ takes a set of propositional formula $\texttt{Fs}$ and a propositional variable assignment $I$.  It returns true only if and only if all formulas from $\texttt{Fs}$ are true given the variable assignment $I$.<jupyter_code>def allTrue(Fs, I):
    return all({evaluate(f, I) for f in Fs})<jupyter_output><empty_output><jupyter_text>Next, we compute the set of all variable assignments that render all formulas true:<jupyter_code>{ I for I in power(P) if allTrue(Fs, I) }<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10172828702690877, 'fraction_numerical': 0.007438197330999781, 'mean_word_length': 4.404255319148936, 'pattern_counts': {'":': 0, '<': 54, '<?xml version=': 0, '>': 54, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '41676', 'license': 'MIT', 'n_tokens_mistral': 1493, 'n_tokens_neox': 1448, 'n_words': 595, 'path': 'Python/Exercises/Blatt-07-Gruppenloesung.ipynb', 'repo_name': 'adroi3/Logic', 'size': '4575'}