\myheading{Fred puzzle} \label{FredPuzzle} Found this: \begin{lstlisting} Three fellows accused of stealing CDs make the following statements: (1) Ed: “Fred did it, and Ted is innocent.” (2) Fred: “If Ed is guilty, then so is Ted.” (3) Ted: “I’m innocent, but at least one of the others is guilty.” If the innocent told the truth and the guilty lied, who is guilty? (Remember that false statements imply anything). I think Ed and Ted are innocent and Fred is guilty. Is it in contradiction with statement 2. What do you say? \end{lstlisting} ( \url{https://math.stackexchange.com/questions/15199/implication-of-three-statements} ) And how to convert this into logic statements: \begin{lstlisting} Let us write the following propositions: Fg means Fred is guilty, and Fi means Fred is innocent, Tg and Ti for Ted and Eg and Ei for Ed. 1. Ed says: Fg §$\wedge$§ Ti 2. Fred says: Eg §$\rightarrow$§ Tg 3. Ted says: Ti §$\wedge$§ (Fg §$\vee$§ Eg) We know that the guilty is lying and the innocent tells the truth. ... \end{lstlisting} This is how I can implement it using Z3Py: \lstinputlisting[style=custompy]{puzzles/fred/fred.py} The result: \begin{lstlisting} sat [fg = False, ti = False, tg = True, eg = True, ei = False, fi = True] \end{lstlisting} (Fred is innocent, others are guilty.) (\TT{Implies} can be replaced with \TT{Or(Not(x), y)}.) Now in SMT-LIB v2 form: \lstinputlisting[style=customsmt]{puzzles/fred/fred.smt2} Again, it's small enough to be solved by MK85: \begin{lstlisting} $ MK85 --dump-internal-variables fred.smt2 sat (model (define-fun always_false () Bool false) ; var_no=1 (define-fun always_true () Bool true) ; var_no=2 (define-fun fg () Bool false) ; var_no=3 (define-fun fi () Bool true) ; var_no=4 (define-fun tg () Bool true) ; var_no=5 (define-fun ti () Bool false) ; var_no=6 (define-fun eg () Bool true) ; var_no=7 (define-fun ei () Bool false) ; var_no=8 (define-fun internal!1 () Bool true) ; var_no=9 (define-fun internal!2 () Bool false) ; var_no=10 (define-fun internal!3 () Bool true) ; var_no=11 (define-fun internal!4 () Bool true) ; var_no=12 (define-fun internal!5 () Bool false) ; var_no=13 (define-fun internal!6 () Bool true) ; var_no=14 (define-fun internal!7 () Bool true) ; var_no=15 (define-fun internal!8 () Bool false) ; var_no=16 (define-fun internal!9 () Bool true) ; var_no=17 (define-fun internal!10 () Bool false) ; var_no=18 (define-fun internal!11 () Bool false) ; var_no=19 (define-fun internal!12 () Bool true) ; var_no=20 (define-fun internal!13 () Bool false) ; var_no=21 (define-fun internal!14 () Bool true) ; var_no=22 (define-fun internal!15 () Bool false) ; var_no=23 (define-fun internal!16 () Bool true) ; var_no=24 (define-fun internal!17 () Bool true) ; var_no=25 (define-fun internal!18 () Bool false) ; var_no=26 (define-fun internal!19 () Bool false) ; var_no=27 (define-fun internal!20 () Bool true) ; var_no=28 ) \end{lstlisting} What is in the CNF file generated by MK85? \lstinputlisting[style=customsat]{puzzles/fred/tmp.cnf} Let's filter out comments: \lstinputlisting[style=customsat]{puzzles/fred/tmp.cnf.comments} % TODO \ref{} Again, this instance is small enough to be solved by small backtracking SAT-solver: \begin{lstlisting} $ python SAT_backtrack.py tmp.cnf SAT -1 2 -3 4 5 -6 7 -8 9 -10 11 12 -13 14 15 -16 17 -18 -19 20 -21 22 -23 24 25 -26 -27 28 0 UNSAT solutions= 1 \end{lstlisting} See also: solving \emph{Fred puzzle} using regex matcher: \ref{regex_SAT}.