#!/bin/bash # Notice: only work when in PATH, or call using absolute path. trap 'quit' 2 15 b=$(tput bold) n=$(tput sgr0) # Operators function disj { [[ $1 == "T" ]] && echo "T" && return [[ $2 == "T" ]] && echo "T" && return echo "F" && return } function conj { [[ $1 == "T" && $2 == "T" ]] && echo "T" && return echo "F" && return } function impl { [[ $1 == "T" && $2 == "F" ]] && echo "F" && return echo "T" && return } function req { impl $2 $1 } function eq { [[ $1 == $2 ]] && echo "T" && return echo "F" && return } function not { [[ $1 == "T" ]] && echo "F" && return echo "T" && return } [[ $1 == source ]] && return # Codegen function mkcode { tmp="$(mktemp)" expr_src="$(cat)" vars="$(_uppercase <<< "$expr_src")" core_expr="$(sed -e 's/(/$(/g; s/[A-Z]/$&/g;s/^$//; ' <<< "$expr_src")" { echo -e '#!/bin/bash\n. '$0' source' for var in $vars; do echo 'echo -n "'$var'; "'; done; [[ ! -z $vars ]] && echo 'echo' for var in $vars; do echo 'for '$var' in T F; do ' done for _var in $vars; do echo 'echo -n "$'$_var'; "' done echo 'echo "'$b'=>'$n' '$core_expr';"; ' for var in $vars; do echo 'done; '; done } > $tmp bash $tmp rm $tmp } function _uppercase { tr ' ' '\n' | grep -E '[A-Z]' | sed 's/.*\([A-Z]\).*/\1/' | sort | uniq | tr '\n' ' ' } function quit { [[ -e "$tmpd" ]] && rm -r "$tmpd" exit 0 } function main { tmpd="$(mktemp -d)" cd $tmpd; touch disj conj impl req eq not echo "nato's logic evaluator (truth table listing) tool, " echo "version: 0.1.2; " echo echo "commands: " echo " disj

: disjunction of p and q. (or)" echo " conj

: conjunction of p and q. (and)" echo " impl

: p implies q. (condition)" echo " req

: p require q. (n. condition)" echo " eq

: p equals q." echo " not

: not p." echo echo "example: (P ⊃ (~R · I)) will be written as: " echo "(impl P (conj (not R) I))" echo echo "note that the outer parentheses are REQUIRED, " echo "anything outside the paren will be treated as formating string. e.g.: " echo "?> conjoining A and B is: (conj A B)" echo "A; B; " echo "T; T; => conjoining T and T is: T;" echo "T; F; => conjoining T and F is: F;" echo "F; T; => conjoining F and T is: F;" echo "F; F; => conjoining F and F is: F;" echo echo "You can also evaluate multiple expressions in same time: e.g.:" echo "?> (not A), (eq (not B) A)" echo "A; B; " echo "T; T; => F, F;" echo "T; F; => F, T;" echo "F; T; => T, T;" echo "F; F; => T, F;" echo while IFS="" read -r -e -d $'\n' -p "$flags$b?>$n " expr_; do history -s "$expr_" mkcode <<< "$expr_" done } main quit