#!/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
: 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
: 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