packages feed

intensional-datatys-0.2.0.0: test/PaperExamples.hs

module Main where

import qualified Data.List as List

type P = Int

data L = Atom P | NegAtom P
  deriving Eq

data Fm = 
    Lit L
    | Not Fm
    | And Fm Fm
    | Or Fm Fm
    | Imp Fm Fm

nnf :: Fm -> Fm
nnf (And p q) = And (nnf p) (nnf q)
nnf (Or p q) = Or (nnf p) (nnf q)
nnf (Imp p q) = Or (nnf (Not p)) (nnf q) 
nnf (Not (Not p)) = nnf p 
nnf (Not (And p q)) = Or (nnf (Not p)) (nnf (Not q))
nnf (Not (Or p q)) = And (nnf (Not p)) (nnf (Not q))
nnf (Not (Imp p q)) = And (nnf p) (nnf (Not q))
nnf (Not (Lit (Atom x))) = Lit (NegAtom x)
nnf (Not (Lit (NegAtom x))) = Lit (Atom x)
nnf (Lit (Atom x)) = Lit (Atom x)
nnf (Lit (NegAtom x)) = Lit (NegAtom x)

distrib xss yss = List.nub [ List.union xs ys | xs <- xss, ys <- yss ]

nnf2dnf (And p q) = distrib (nnf2dnf p) (nnf2dnf q)
nnf2dnf (Or p q)  = List.union (nnf2dnf p) (nnf2dnf q)
nnf2dnf (Lit a)   = [[a]]
nnf2dnf _         = error "Impossible!"

dnf = nnf2dnf . nnf

k x y = x

data Arith = L Int | Plus | Mult
data Lam = Cst Arith | App Lam Lam | Abs (Lam -> Lam) | FVr String | BVr Int

lkup :: [(String,a)] -> String -> a
lkup ((s,x):ps) t = if s == t then x else lkup ps t

cloSub :: [(String, Lam)] -> Lam -> Lam
cloSub m (FVr s) = lkup m s
cloSub m (Cst c) = Cst c
cloSub m (App u v) = App (cloSub m u) (cloSub m v)

f :: Lam -> Lam
f x = k x (f (f x))

-- Bugs

nnf' :: Fm -> Fm
nnf' (And p q) = And (nnf' p) (nnf' q)
nnf' (Or p q) = Or (nnf' p) (nnf' q)
nnf' (Imp p q) = Or (Not (nnf' p)) (nnf' q) 
nnf' (Not (Not p)) = nnf' p 
nnf' (Not (And p q)) = Or (nnf' (Not p)) (nnf' (Not q))
nnf' (Not (Or p q)) = And (nnf' (Not p)) (nnf' (Not q))
nnf' (Not (Imp p q)) = And (nnf' p) (nnf' (Not q))
nnf' (Not (Lit (Atom x))) = Lit (NegAtom x)
nnf' (Not (Lit (NegAtom x))) = Lit (Atom x)
nnf' (Lit (Atom x)) = Lit (Atom x)
nnf' (Lit (NegAtom x)) = Lit (NegAtom x)

dnf' = nnf2dnf . nnf'

willNotCrash = dnf' (And (Lit (Atom 1)) (Lit (Atom 2)))
willCrash = 
  dnf' (Imp (Lit (Atom 1)) 
            (And (Lit (Atom 2)) 
                 (Or (Lit (NegAtom 3)) (Lit (Atom 1)))))

main :: IO ()
main = return ()