aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Logic.dcl12
-rw-r--r--Logic.icl109
-rw-r--r--LogicTest.icl8
3 files changed, 107 insertions, 22 deletions
diff --git a/Logic.dcl b/Logic.dcl
index 90d579b..bf76859 100644
--- a/Logic.dcl
+++ b/Logic.dcl
@@ -40,6 +40,14 @@ isEquiv :: Expr -> Bool
instance toString Op1
instance toString Op2
instance toString Expr
+instance toString TruthTable
+
+instance == Op1
+instance < Op1
+instance == Op2
+instance < Op2
+instance == Expr
+instance < Expr // To sort by unrigorous 'complexity'; e.g. in truthtables
binds_stronger :: Op2 Op2 -> Bool // True iff arg1 stronger binds than arg2
@@ -50,5 +58,7 @@ substitute :: AtomOption Expr -> Expr // Substitute all atomic expressions
substitute_all :: [AtomOption] Expr -> Expr // Same, for multiple options
eval :: Expr -> [Bool] // Evaluate to a simpler form
-instance toString TruthTable
+subexprs :: Expr -> [Expr] // Subexpressions of an expression
+sorted_subexprs :: (Expr -> [Expr]) // Similar, but roughly sorted by complexity
+truthtable :: Expr -> TruthTable // Truthtable from an expression
diff --git a/Logic.icl b/Logic.icl
index 7ebf98f..24ce94d 100644
--- a/Logic.icl
+++ b/Logic.icl
@@ -77,6 +77,88 @@ where
| needs_parentheses_right (App2 e1 op e2) = "(" +++ toString e2 +++ ")"
| otherwise = toString e2
+instance toString TruthTable
+where
+ toString t=:{exprs,options}
+ = row_b +++ join row_s [pad_right head len \\ head <- map toString exprs & len <- padlens] +++ row_e +++
+ line_b +++ join line_s [toString (repeatn len '-') \\ len <- padlens] +++ line_e +++
+ foldr (+++) "" [row_b +++ join row_s [pad_right (toStringOrEmpty val) len \\ val <- map (eval o substitute_all options`) exprs & len <- padlens] +++ row_e \\ options` <- options]
+ //= foldr (+++) "" (map toString padlens)
+ where
+ row_b = " "
+ row_e = " \n"
+ row_s = " | "
+ line_b = "-"
+ line_e = "-\n"
+ line_s = "-+-"
+ padlens = map ((max 5) o strlen o toString) exprs
+ toStringOrEmpty :: [Bool] -> String
+ toStringOrEmpty [] = ""
+ toStringOrEmpty [b:bs] = toString b
+
+instance == Op1
+where
+ (==) Not Not = True
+
+instance < Op1
+where
+ (<) Not Not = False // this doesn't make much sense, but whatever
+
+instance == Op2
+where
+ (==) And And = True
+ (==) Or Or = True
+ (==) Impl Impl = True
+ (==) Equiv Equiv = True
+ (==) _ _ = False
+
+instance < Op2
+where
+ (<) op1 op2
+ | op1 == op2 = False
+ | otherwise = comp op1 op2
+ where
+ comp And And = False
+ comp And _ = True
+ comp _ And = False
+ comp Or Or = False
+ comp Or _ = True
+ comp _ Or = False
+ comp Impl Impl = False
+ comp Impl _ = True
+ comp Equiv Equiv = False
+
+instance == Expr
+where
+ (==) (B b1) (B b2) = b1 == b2
+ (==) (Atom a1) (Atom a2) = a1 == a2
+ (==) (App1 op e) (App1 op` e`) = op == op` && e == e`
+ (==) (App2 e1 op e2) (App2 e1` op` e2`) = e1 == e1` && op == op` && e2 == e2`
+ (==) _ _ = False
+
+instance < Expr
+where
+ (<) e1 e2
+ | e1 == e2 = False
+ | otherwise = comp e1 e2
+ where
+ comp (B False) _ = True
+ comp _ (B False) = False
+ comp (B _) _ = True
+ comp _ (B _) = False
+ comp (Atom a) (Atom b) = a < b
+ comp (Atom _) _ = True
+ comp _ (Atom _) = False
+ comp (App1 _ e) (App1 _ e`) = e < e`
+ comp (App1 _ _) _ = True
+ comp _ (App1 _ _) = False
+ comp (App2 e1 op e2) (App2 e1` op` e2`)
+ | e1 < e1` = True
+ | e1` < e1 = False
+ | e2 < e2` = True
+ | e2` < e2 = False
+ | otherwise = op < op`
+
needs_parentheses :: Expr -> Bool
needs_parentheses (App1 Not (B _)) = False
needs_parentheses (App1 Not (Atom _)) = False
@@ -141,26 +223,17 @@ eval (App1 op e) = [apply1 op e` \\ e` <- eval e]
eval (App2 e1 op e2) = [apply2 e1` op e2` \\ e1` <- eval e1 & e2` <- eval e2]
eval _ = []
-instance toString TruthTable
-where
- toString t=:{exprs,options}
- = row_b +++ join row_s [pad_right head len \\ head <- map toString exprs & len <- padlens] +++ row_e +++
- line_b +++ join line_s [toString (repeatn len '-') \\ len <- padlens] +++ line_e +++
- foldr (+++) "" [row_b +++ join row_s [pad_right (toStringOrEmpty val) len \\ val <- map (eval o substitute_all options`) exprs & len <- padlens] +++ row_e \\ options` <- options]
- //= foldr (+++) "" (map toString padlens)
- where
- row_b = " "
- row_e = " \n"
- row_s = " | "
- line_b = "-"
- line_e = "-\n"
- line_s = "-+-"
- padlens = map ((max 5) o strlen o toString) exprs
- toStringOrEmpty :: [Bool] -> String
- toStringOrEmpty [] = ""
- toStringOrEmpty [b:bs] = toString b
+subexprs :: Expr -> [Expr]
+subexprs (B _) = []
+subexprs (Atom _) = []
+subexprs (App1 op e) = removeDup (subexprs e ++ [e])
+subexprs (App2 e1 op e2) = removeDup (subexprs e1 ++ subexprs e2 ++ [e1,e2])
+sorted_subexprs :: (Expr -> [Expr])
+sorted_subexprs = sort o subexprs
+truthtable :: Expr -> TruthTable
+truthtable e = {exprs = sorted_subexprs e ++ [e], options = all_atom_options e}
diff --git a/LogicTest.icl b/LogicTest.icl
index 4122b92..7f6f214 100644
--- a/LogicTest.icl
+++ b/LogicTest.icl
@@ -1,6 +1,6 @@
module LogicTest
-import Logic
+import Logic, StringUtils
// Some random examples
e1 = Atom 'p'
@@ -35,6 +35,8 @@ exprs_assoc = [e10,e11,e12,e13,e14,e15,e16,e17]
//Start = substitute ('q',True) e8
table = { exprs = exprs_rand ++ exprs_assoc,
- options = all_atom_options e4 }
+ options = all_atom_options e10 }
-Start = toString table
+//Start = join ", " (map toString [e17 : subexprs e17])
+
+Start = toString (truthtable (App2 e9 And e7))