aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Logic.dcl38
-rw-r--r--Logic.icl101
-rw-r--r--LogicParser.icl18
3 files changed, 157 insertions, 0 deletions
diff --git a/Logic.dcl b/Logic.dcl
new file mode 100644
index 0000000..767990f
--- /dev/null
+++ b/Logic.dcl
@@ -0,0 +1,38 @@
+definition module Logic
+
+import StdEnv
+
+// Expressions
+:: Expr = B Bool // A constant
+ | Atom AtomName // An atomic expression
+ | App1 Op1 Expr // Applying an Op1 on an expression
+ | App2 Expr Op2 Expr // Applying an Op2 on two expressions
+
+// Operators with one argument
+:: Op1 = Not // logical not
+
+// Operators with two arguments
+:: Op2 = And // logical and; left-associative
+ | Or // logical or; right-associative
+ | Impl // material implication; right-associative
+ | Equiv // equivalence; right-associative
+
+// All Chars may be used, but typically only [a-zA-Z] are used
+:: AtomName :== Char
+
+isBool :: Expr -> Bool
+isAtom :: Expr -> Bool
+isApp1 :: Expr -> Bool
+isApp2 :: Expr -> Bool
+isApp :: Expr -> Bool
+
+isNot :: Expr -> Bool
+isAnd :: Expr -> Bool
+isOr :: Expr -> Bool
+isImpl :: Expr -> Bool
+isEquiv :: Expr -> Bool
+
+instance toString Op1
+instance toString Op2
+instance toString Expr
+
diff --git a/Logic.icl b/Logic.icl
new file mode 100644
index 0000000..0276305
--- /dev/null
+++ b/Logic.icl
@@ -0,0 +1,101 @@
+implementation module Logic
+
+import StdEnv
+
+isBool :: Expr -> Bool
+isBool (B _) = True
+isBool _ = False
+
+isAtom :: Expr -> Bool
+isAtom (Atom _) = True
+isAtom _ = False
+
+isApp1 :: Expr -> Bool
+isApp1 (App1 _ _) = True
+isApp1 _ = False
+
+isApp2 :: Expr -> Bool
+isApp2 (App2 _ _ _) = True
+isApp2 _ = False
+
+isApp :: Expr -> Bool
+isApp e = isApp1 e || isApp2 e
+
+isNot :: Expr -> Bool
+isNot (App1 Not _) = True
+isNot _ = False
+
+isAnd :: Expr -> Bool
+isAnd (App2 _ And _) = True
+isAnd _ = False
+
+isOr :: Expr -> Bool
+isOr (App2 _ Or _) = True
+isOr _ = False
+
+isImpl :: Expr -> Bool
+isImpl (App2 _ Impl _) = True
+isImpl _ = False
+
+isEquiv :: Expr -> Bool
+isEquiv (App2 _ Equiv _) = True
+isEquiv _ = False
+
+instance toString Op1
+where
+ toString Not = "~"
+
+instance toString Op2
+where
+ toString And = "&"
+ toString Or = "|"
+ toString Impl = "->"
+ toString Equiv = "<->"
+
+instance toString Expr
+where
+ toString (B True) = toString 1
+ toString (B False) = toString 0
+ toString (Atom a) = toString a
+ toString (App1 op e)
+ | needs_parentheses (App1 op e) = toString op +++ "(" +++ toString e +++ ")"
+ | otherwise = toString op +++ toString e
+ toString (App2 e1 op e2) = e1` +++ " " +++ toString op +++ " " +++ e2`
+ where
+ e1`
+ | needs_parentheses_left (App2 e1 op e2) = "(" +++ toString e1 +++ ")"
+ | otherwise = toString e1
+ e2`
+ | needs_parentheses_right (App2 e1 op e2) = "(" +++ toString e2 +++ ")"
+ | otherwise = toString e2
+
+needs_parentheses :: Expr -> Bool
+needs_parentheses (App1 Not (B _)) = False
+needs_parentheses (App1 Not (Atom _)) = False
+needs_parentheses (App1 Not (App1 Not _)) = False
+needs_parentheses _ = True
+
+needs_parentheses_left :: Expr -> Bool
+needs_parentheses_left (App2 (B _) _ _) = False
+needs_parentheses_left (App2 (Atom _) _ _) = False
+needs_parentheses_left (App2 (App1 Not _) _ _) = False
+needs_parentheses_left (App2 (App2 _ op1 _) op2 _) = binds_stronger op2 op1
+
+needs_parentheses_right :: Expr -> Bool
+needs_parentheses_right (App2 _ _ (B _)) = False
+needs_parentheses_right (App2 _ _ (Atom _)) = False
+needs_parentheses_right (App2 _ _ (App1 Not _)) = False
+needs_parentheses_right (App2 _ op1 (App2 _ op2 _)) = binds_stronger op1 op2
+
+// Associativity rules
+binds_stronger :: Op2 Op2 -> Bool
+binds_stronger And _ = True // And is left-associative
+binds_stronger _ And = False
+binds_stronger Or Or = False // All others are right-associative
+binds_stronger Or _ = True
+binds_stronger _ Or = False
+binds_stronger Impl Impl = False
+binds_stronger Impl _ = True
+binds_stronger _ Impl = False
+binds_stronger Equiv Equiv = False
+
diff --git a/LogicParser.icl b/LogicParser.icl
new file mode 100644
index 0000000..ef81237
--- /dev/null
+++ b/LogicParser.icl
@@ -0,0 +1,18 @@
+module LogicParser
+
+import Logic
+
+e1 = Atom 'p'
+e2 = Atom 'q'
+e3 = App1 Not e1
+e4 = App2 e1 And e2
+e5 = App2 e3 Or e2
+e6 = App2 e3 Impl e3
+e7 = App2 e4 Equiv e5
+
+e8 = App2 (App2 (Atom 'p') And (Atom 'q')) Impl (Atom 'q')
+e9 = App2 (Atom 'p') And (App2 (Atom 'q') Impl (Atom 'q'))
+
+exprs = [e1,e2,e3,e4,e5,e6,e7,e8,e9]
+
+Start = map toString exprs