{-# Language PolyKinds, DataKinds, TemplateHaskell, TypeFamilies,
    GADTs, TypeOperators, RankNTypes, FlexibleContexts, UndecidableInstances,
    FlexibleInstances, ScopedTypeVariables, MultiParamTypeClasses,
    OverlappingInstances, KindSignatures, DeriveDataTypeable #-}
module Oxymoron.Description.Symbol where
import Data.Singletons
import Language.Haskell.TH
import Data.Data


singletons [d| 
    data Nat = Zero | Succ Nat deriving (Show, Eq, Ord)

    data AChar = CA | CB | CC | CD | CE | CF | CG | CH | CI
               | CJ | CK | CL | CM | CN | CO | CP | CQ | CR
               | CS | CT | CU | CV | CW | CX | CY | CZ
               deriving (Read, Show, Eq, Enum, Ord) 
    data Symbol = Symbol [AChar]
               deriving (Read, Show, Eq) 
               
    data SymbolList = SymbolList [Symbol]
    
    proj :: Bool -> Bool -> Bool
    proj True True = True
    proj True False = True
    proj False True = False
    proj False False = False
    
    leqNat :: Nat -> Nat -> Bool
    leqNat Zero _ = True
    leqNat (Succ _) Zero = False
    leqNat (Succ a) (Succ b) = leqNat a b
    
    leqAChar :: AChar -> AChar -> Bool
    leqAChar CA CA = False
    leqAChar CA CB = True
    leqAChar CA CC = True
    leqAChar CA CD = True
    leqAChar CA CE = True
    leqAChar CA CF = True
    leqAChar CA CG = True
    leqAChar CA CH = True
    leqAChar CA CI = True
    leqAChar CA CJ = True
    leqAChar CA CK = True
    leqAChar CA CL = True
    leqAChar CA CM = True
    leqAChar CA CN = True
    leqAChar CA CO = True
    leqAChar CA CP = True
    leqAChar CA CQ = True
    leqAChar CA CR = True
    leqAChar CA CS = True
    leqAChar CA CT = True
    leqAChar CA CU = True
    leqAChar CA CV = True
    leqAChar CA CW = True
    leqAChar CA CX = True
    leqAChar CA CY = True
    leqAChar CA CZ = True
    leqAChar CB CA = False
    leqAChar CB CB = False
    leqAChar CB CC = True
    leqAChar CB CD = True
    leqAChar CB CE = True
    leqAChar CB CF = True
    leqAChar CB CG = True
    leqAChar CB CH = True
    leqAChar CB CI = True
    leqAChar CB CJ = True
    leqAChar CB CK = True
    leqAChar CB CL = True
    leqAChar CB CM = True
    leqAChar CB CN = True
    leqAChar CB CO = True
    leqAChar CB CP = True
    leqAChar CB CQ = True
    leqAChar CB CR = True
    leqAChar CB CS = True
    leqAChar CB CT = True
    leqAChar CB CU = True
    leqAChar CB CV = True
    leqAChar CB CW = True
    leqAChar CB CX = True
    leqAChar CB CY = True
    leqAChar CB CZ = True
    leqAChar CC CA = False
    leqAChar CC CB = False
    leqAChar CC CC = False
    leqAChar CC CD = True
    leqAChar CC CE = True
    leqAChar CC CF = True
    leqAChar CC CG = True
    leqAChar CC CH = True
    leqAChar CC CI = True
    leqAChar CC CJ = True
    leqAChar CC CK = True
    leqAChar CC CL = True
    leqAChar CC CM = True
    leqAChar CC CN = True
    leqAChar CC CO = True
    leqAChar CC CP = True
    leqAChar CC CQ = True
    leqAChar CC CR = True
    leqAChar CC CS = True
    leqAChar CC CT = True
    leqAChar CC CU = True
    leqAChar CC CV = True
    leqAChar CC CW = True
    leqAChar CC CX = True
    leqAChar CC CY = True
    leqAChar CC CZ = True
    leqAChar CD CA = False
    leqAChar CD CB = False
    leqAChar CD CC = False
    leqAChar CD CD = False
    leqAChar CD CE = True
    leqAChar CD CF = True
    leqAChar CD CG = True
    leqAChar CD CH = True
    leqAChar CD CI = True
    leqAChar CD CJ = True
    leqAChar CD CK = True
    leqAChar CD CL = True
    leqAChar CD CM = True
    leqAChar CD CN = True
    leqAChar CD CO = True
    leqAChar CD CP = True
    leqAChar CD CQ = True
    leqAChar CD CR = True
    leqAChar CD CS = True
    leqAChar CD CT = True
    leqAChar CD CU = True
    leqAChar CD CV = True
    leqAChar CD CW = True
    leqAChar CD CX = True
    leqAChar CD CY = True
    leqAChar CD CZ = True
    leqAChar CE CA = False
    leqAChar CE CB = False
    leqAChar CE CC = False
    leqAChar CE CD = False
    leqAChar CE CE = False
    leqAChar CE CF = True
    leqAChar CE CG = True
    leqAChar CE CH = True
    leqAChar CE CI = True
    leqAChar CE CJ = True
    leqAChar CE CK = True
    leqAChar CE CL = True
    leqAChar CE CM = True
    leqAChar CE CN = True
    leqAChar CE CO = True
    leqAChar CE CP = True
    leqAChar CE CQ = True
    leqAChar CE CR = True
    leqAChar CE CS = True
    leqAChar CE CT = True
    leqAChar CE CU = True
    leqAChar CE CV = True
    leqAChar CE CW = True
    leqAChar CE CX = True
    leqAChar CE CY = True
    leqAChar CE CZ = True
    leqAChar CF CA = False
    leqAChar CF CB = False
    leqAChar CF CC = False
    leqAChar CF CD = False
    leqAChar CF CE = False
    leqAChar CF CF = False
    leqAChar CF CG = True
    leqAChar CF CH = True
    leqAChar CF CI = True
    leqAChar CF CJ = True
    leqAChar CF CK = True
    leqAChar CF CL = True
    leqAChar CF CM = True
    leqAChar CF CN = True
    leqAChar CF CO = True
    leqAChar CF CP = True
    leqAChar CF CQ = True
    leqAChar CF CR = True
    leqAChar CF CS = True
    leqAChar CF CT = True
    leqAChar CF CU = True
    leqAChar CF CV = True
    leqAChar CF CW = True
    leqAChar CF CX = True
    leqAChar CF CY = True
    leqAChar CF CZ = True
    leqAChar CG CA = False
    leqAChar CG CB = False
    leqAChar CG CC = False
    leqAChar CG CD = False
    leqAChar CG CE = False
    leqAChar CG CF = False
    leqAChar CG CG = False
    leqAChar CG CH = True
    leqAChar CG CI = True
    leqAChar CG CJ = True
    leqAChar CG CK = True
    leqAChar CG CL = True
    leqAChar CG CM = True
    leqAChar CG CN = True
    leqAChar CG CO = True
    leqAChar CG CP = True
    leqAChar CG CQ = True
    leqAChar CG CR = True
    leqAChar CG CS = True
    leqAChar CG CT = True
    leqAChar CG CU = True
    leqAChar CG CV = True
    leqAChar CG CW = True
    leqAChar CG CX = True
    leqAChar CG CY = True
    leqAChar CG CZ = True
    leqAChar CH CA = False
    leqAChar CH CB = False
    leqAChar CH CC = False
    leqAChar CH CD = False
    leqAChar CH CE = False
    leqAChar CH CF = False
    leqAChar CH CG = False
    leqAChar CH CH = False
    leqAChar CH CI = True
    leqAChar CH CJ = True
    leqAChar CH CK = True
    leqAChar CH CL = True
    leqAChar CH CM = True
    leqAChar CH CN = True
    leqAChar CH CO = True
    leqAChar CH CP = True
    leqAChar CH CQ = True
    leqAChar CH CR = True
    leqAChar CH CS = True
    leqAChar CH CT = True
    leqAChar CH CU = True
    leqAChar CH CV = True
    leqAChar CH CW = True
    leqAChar CH CX = True
    leqAChar CH CY = True
    leqAChar CH CZ = True
    leqAChar CI CA = False
    leqAChar CI CB = False
    leqAChar CI CC = False
    leqAChar CI CD = False
    leqAChar CI CE = False
    leqAChar CI CF = False
    leqAChar CI CG = False
    leqAChar CI CH = False
    leqAChar CI CI = False
    leqAChar CI CJ = True
    leqAChar CI CK = True
    leqAChar CI CL = True
    leqAChar CI CM = True
    leqAChar CI CN = True
    leqAChar CI CO = True
    leqAChar CI CP = True
    leqAChar CI CQ = True
    leqAChar CI CR = True
    leqAChar CI CS = True
    leqAChar CI CT = True
    leqAChar CI CU = True
    leqAChar CI CV = True
    leqAChar CI CW = True
    leqAChar CI CX = True
    leqAChar CI CY = True
    leqAChar CI CZ = True
    leqAChar CJ CA = False
    leqAChar CJ CB = False
    leqAChar CJ CC = False
    leqAChar CJ CD = False
    leqAChar CJ CE = False
    leqAChar CJ CF = False
    leqAChar CJ CG = False
    leqAChar CJ CH = False
    leqAChar CJ CI = False
    leqAChar CJ CJ = False
    leqAChar CJ CK = True
    leqAChar CJ CL = True
    leqAChar CJ CM = True
    leqAChar CJ CN = True
    leqAChar CJ CO = True
    leqAChar CJ CP = True
    leqAChar CJ CQ = True
    leqAChar CJ CR = True
    leqAChar CJ CS = True
    leqAChar CJ CT = True
    leqAChar CJ CU = True
    leqAChar CJ CV = True
    leqAChar CJ CW = True
    leqAChar CJ CX = True
    leqAChar CJ CY = True
    leqAChar CJ CZ = True
    leqAChar CK CA = False
    leqAChar CK CB = False
    leqAChar CK CC = False
    leqAChar CK CD = False
    leqAChar CK CE = False
    leqAChar CK CF = False
    leqAChar CK CG = False
    leqAChar CK CH = False
    leqAChar CK CI = False
    leqAChar CK CJ = False
    leqAChar CK CK = False
    leqAChar CK CL = True
    leqAChar CK CM = True
    leqAChar CK CN = True
    leqAChar CK CO = True
    leqAChar CK CP = True
    leqAChar CK CQ = True
    leqAChar CK CR = True
    leqAChar CK CS = True
    leqAChar CK CT = True
    leqAChar CK CU = True
    leqAChar CK CV = True
    leqAChar CK CW = True
    leqAChar CK CX = True
    leqAChar CK CY = True
    leqAChar CK CZ = True
    leqAChar CL CA = False
    leqAChar CL CB = False
    leqAChar CL CC = False
    leqAChar CL CD = False
    leqAChar CL CE = False
    leqAChar CL CF = False
    leqAChar CL CG = False
    leqAChar CL CH = False
    leqAChar CL CI = False
    leqAChar CL CJ = False
    leqAChar CL CK = False
    leqAChar CL CL = False
    leqAChar CL CM = True
    leqAChar CL CN = True
    leqAChar CL CO = True
    leqAChar CL CP = True
    leqAChar CL CQ = True
    leqAChar CL CR = True
    leqAChar CL CS = True
    leqAChar CL CT = True
    leqAChar CL CU = True
    leqAChar CL CV = True
    leqAChar CL CW = True
    leqAChar CL CX = True
    leqAChar CL CY = True
    leqAChar CL CZ = True
    leqAChar CM CA = False
    leqAChar CM CB = False
    leqAChar CM CC = False
    leqAChar CM CD = False
    leqAChar CM CE = False
    leqAChar CM CF = False
    leqAChar CM CG = False
    leqAChar CM CH = False
    leqAChar CM CI = False
    leqAChar CM CJ = False
    leqAChar CM CK = False
    leqAChar CM CL = False
    leqAChar CM CM = False
    leqAChar CM CN = True
    leqAChar CM CO = True
    leqAChar CM CP = True
    leqAChar CM CQ = True
    leqAChar CM CR = True
    leqAChar CM CS = True
    leqAChar CM CT = True
    leqAChar CM CU = True
    leqAChar CM CV = True
    leqAChar CM CW = True
    leqAChar CM CX = True
    leqAChar CM CY = True
    leqAChar CM CZ = True
    leqAChar CN CA = False
    leqAChar CN CB = False
    leqAChar CN CC = False
    leqAChar CN CD = False
    leqAChar CN CE = False
    leqAChar CN CF = False
    leqAChar CN CG = False
    leqAChar CN CH = False
    leqAChar CN CI = False
    leqAChar CN CJ = False
    leqAChar CN CK = False
    leqAChar CN CL = False
    leqAChar CN CM = False
    leqAChar CN CN = False
    leqAChar CN CO = True
    leqAChar CN CP = True
    leqAChar CN CQ = True
    leqAChar CN CR = True
    leqAChar CN CS = True
    leqAChar CN CT = True
    leqAChar CN CU = True
    leqAChar CN CV = True
    leqAChar CN CW = True
    leqAChar CN CX = True
    leqAChar CN CY = True
    leqAChar CN CZ = True
    leqAChar CO CA = False
    leqAChar CO CB = False
    leqAChar CO CC = False
    leqAChar CO CD = False
    leqAChar CO CE = False
    leqAChar CO CF = False
    leqAChar CO CG = False
    leqAChar CO CH = False
    leqAChar CO CI = False
    leqAChar CO CJ = False
    leqAChar CO CK = False
    leqAChar CO CL = False
    leqAChar CO CM = False
    leqAChar CO CN = False
    leqAChar CO CO = False
    leqAChar CO CP = True
    leqAChar CO CQ = True
    leqAChar CO CR = True
    leqAChar CO CS = True
    leqAChar CO CT = True
    leqAChar CO CU = True
    leqAChar CO CV = True
    leqAChar CO CW = True
    leqAChar CO CX = True
    leqAChar CO CY = True
    leqAChar CO CZ = True
    leqAChar CP CA = False
    leqAChar CP CB = False
    leqAChar CP CC = False
    leqAChar CP CD = False
    leqAChar CP CE = False
    leqAChar CP CF = False
    leqAChar CP CG = False
    leqAChar CP CH = False
    leqAChar CP CI = False
    leqAChar CP CJ = False
    leqAChar CP CK = False
    leqAChar CP CL = False
    leqAChar CP CM = False
    leqAChar CP CN = False
    leqAChar CP CO = False
    leqAChar CP CP = False
    leqAChar CP CQ = True
    leqAChar CP CR = True
    leqAChar CP CS = True
    leqAChar CP CT = True
    leqAChar CP CU = True
    leqAChar CP CV = True
    leqAChar CP CW = True
    leqAChar CP CX = True
    leqAChar CP CY = True
    leqAChar CP CZ = True
    leqAChar CQ CA = False
    leqAChar CQ CB = False
    leqAChar CQ CC = False
    leqAChar CQ CD = False
    leqAChar CQ CE = False
    leqAChar CQ CF = False
    leqAChar CQ CG = False
    leqAChar CQ CH = False
    leqAChar CQ CI = False
    leqAChar CQ CJ = False
    leqAChar CQ CK = False
    leqAChar CQ CL = False
    leqAChar CQ CM = False
    leqAChar CQ CN = False
    leqAChar CQ CO = False
    leqAChar CQ CP = False
    leqAChar CQ CQ = False
    leqAChar CQ CR = True
    leqAChar CQ CS = True
    leqAChar CQ CT = True
    leqAChar CQ CU = True
    leqAChar CQ CV = True
    leqAChar CQ CW = True
    leqAChar CQ CX = True
    leqAChar CQ CY = True
    leqAChar CQ CZ = True
    leqAChar CR CA = False
    leqAChar CR CB = False
    leqAChar CR CC = False
    leqAChar CR CD = False
    leqAChar CR CE = False
    leqAChar CR CF = False
    leqAChar CR CG = False
    leqAChar CR CH = False
    leqAChar CR CI = False
    leqAChar CR CJ = False
    leqAChar CR CK = False
    leqAChar CR CL = False
    leqAChar CR CM = False
    leqAChar CR CN = False
    leqAChar CR CO = False
    leqAChar CR CP = False
    leqAChar CR CQ = False
    leqAChar CR CR = False
    leqAChar CR CS = True
    leqAChar CR CT = True
    leqAChar CR CU = True
    leqAChar CR CV = True
    leqAChar CR CW = True
    leqAChar CR CX = True
    leqAChar CR CY = True
    leqAChar CR CZ = True
    leqAChar CS CA = False
    leqAChar CS CB = False
    leqAChar CS CC = False
    leqAChar CS CD = False
    leqAChar CS CE = False
    leqAChar CS CF = False
    leqAChar CS CG = False
    leqAChar CS CH = False
    leqAChar CS CI = False
    leqAChar CS CJ = False
    leqAChar CS CK = False
    leqAChar CS CL = False
    leqAChar CS CM = False
    leqAChar CS CN = False
    leqAChar CS CO = False
    leqAChar CS CP = False
    leqAChar CS CQ = False
    leqAChar CS CR = False
    leqAChar CS CS = False
    leqAChar CS CT = True
    leqAChar CS CU = True
    leqAChar CS CV = True
    leqAChar CS CW = True
    leqAChar CS CX = True
    leqAChar CS CY = True
    leqAChar CS CZ = True
    leqAChar CT CA = False
    leqAChar CT CB = False
    leqAChar CT CC = False
    leqAChar CT CD = False
    leqAChar CT CE = False
    leqAChar CT CF = False
    leqAChar CT CG = False
    leqAChar CT CH = False
    leqAChar CT CI = False
    leqAChar CT CJ = False
    leqAChar CT CK = False
    leqAChar CT CL = False
    leqAChar CT CM = False
    leqAChar CT CN = False
    leqAChar CT CO = False
    leqAChar CT CP = False
    leqAChar CT CQ = False
    leqAChar CT CR = False
    leqAChar CT CS = False
    leqAChar CT CT = False
    leqAChar CT CU = True
    leqAChar CT CV = True
    leqAChar CT CW = True
    leqAChar CT CX = True
    leqAChar CT CY = True
    leqAChar CT CZ = True
    leqAChar CU CA = False
    leqAChar CU CB = False
    leqAChar CU CC = False
    leqAChar CU CD = False
    leqAChar CU CE = False
    leqAChar CU CF = False
    leqAChar CU CG = False
    leqAChar CU CH = False
    leqAChar CU CI = False
    leqAChar CU CJ = False
    leqAChar CU CK = False
    leqAChar CU CL = False
    leqAChar CU CM = False
    leqAChar CU CN = False
    leqAChar CU CO = False
    leqAChar CU CP = False
    leqAChar CU CQ = False
    leqAChar CU CR = False
    leqAChar CU CS = False
    leqAChar CU CT = False
    leqAChar CU CU = False
    leqAChar CU CV = True
    leqAChar CU CW = True
    leqAChar CU CX = True
    leqAChar CU CY = True
    leqAChar CU CZ = True
    leqAChar CV CA = False
    leqAChar CV CB = False
    leqAChar CV CC = False
    leqAChar CV CD = False
    leqAChar CV CE = False
    leqAChar CV CF = False
    leqAChar CV CG = False
    leqAChar CV CH = False
    leqAChar CV CI = False
    leqAChar CV CJ = False
    leqAChar CV CK = False
    leqAChar CV CL = False
    leqAChar CV CM = False
    leqAChar CV CN = False
    leqAChar CV CO = False
    leqAChar CV CP = False
    leqAChar CV CQ = False
    leqAChar CV CR = False
    leqAChar CV CS = False
    leqAChar CV CT = False
    leqAChar CV CU = False
    leqAChar CV CV = False
    leqAChar CV CW = True
    leqAChar CV CX = True
    leqAChar CV CY = True
    leqAChar CV CZ = True
    leqAChar CW CA = False
    leqAChar CW CB = False
    leqAChar CW CC = False
    leqAChar CW CD = False
    leqAChar CW CE = False
    leqAChar CW CF = False
    leqAChar CW CG = False
    leqAChar CW CH = False
    leqAChar CW CI = False
    leqAChar CW CJ = False
    leqAChar CW CK = False
    leqAChar CW CL = False
    leqAChar CW CM = False
    leqAChar CW CN = False
    leqAChar CW CO = False
    leqAChar CW CP = False
    leqAChar CW CQ = False
    leqAChar CW CR = False
    leqAChar CW CS = False
    leqAChar CW CT = False
    leqAChar CW CU = False
    leqAChar CW CV = False
    leqAChar CW CW = False
    leqAChar CW CX = True
    leqAChar CW CY = True
    leqAChar CW CZ = True
    leqAChar CX CA = False
    leqAChar CX CB = False
    leqAChar CX CC = False
    leqAChar CX CD = False
    leqAChar CX CE = False
    leqAChar CX CF = False
    leqAChar CX CG = False
    leqAChar CX CH = False
    leqAChar CX CI = False
    leqAChar CX CJ = False
    leqAChar CX CK = False
    leqAChar CX CL = False
    leqAChar CX CM = False
    leqAChar CX CN = False
    leqAChar CX CO = False
    leqAChar CX CP = False
    leqAChar CX CQ = False
    leqAChar CX CR = False
    leqAChar CX CS = False
    leqAChar CX CT = False
    leqAChar CX CU = False
    leqAChar CX CV = False
    leqAChar CX CW = False
    leqAChar CX CX = False
    leqAChar CX CY = True
    leqAChar CX CZ = True
    leqAChar CY CA = False
    leqAChar CY CB = False
    leqAChar CY CC = False
    leqAChar CY CD = False
    leqAChar CY CE = False
    leqAChar CY CF = False
    leqAChar CY CG = False
    leqAChar CY CH = False
    leqAChar CY CI = False
    leqAChar CY CJ = False
    leqAChar CY CK = False
    leqAChar CY CL = False
    leqAChar CY CM = False
    leqAChar CY CN = False
    leqAChar CY CO = False
    leqAChar CY CP = False
    leqAChar CY CQ = False
    leqAChar CY CR = False
    leqAChar CY CS = False
    leqAChar CY CT = False
    leqAChar CY CU = False
    leqAChar CY CV = False
    leqAChar CY CW = False
    leqAChar CY CX = False
    leqAChar CY CY = False
    leqAChar CY CZ = True
    leqAChar CZ CA = False
    leqAChar CZ CB = False
    leqAChar CZ CC = False
    leqAChar CZ CD = False
    leqAChar CZ CE = False
    leqAChar CZ CF = False
    leqAChar CZ CG = False
    leqAChar CZ CH = False
    leqAChar CZ CI = False
    leqAChar CZ CJ = False
    leqAChar CZ CK = False
    leqAChar CZ CL = False
    leqAChar CZ CM = False
    leqAChar CZ CN = False
    leqAChar CZ CO = False
    leqAChar CZ CP = False
    leqAChar CZ CQ = False
    leqAChar CZ CR = False
    leqAChar CZ CS = False
    leqAChar CZ CT = False
    leqAChar CZ CU = False
    leqAChar CZ CV = False
    leqAChar CZ CW = False
    leqAChar CZ CX = False
    leqAChar CZ CY = False
    leqAChar CZ CZ = False

    
    leqSymbol :: Symbol -> Symbol -> Bool
    leqSymbol (Symbol [])     (Symbol _)      = False
    leqSymbol (Symbol (x:_))  (Symbol [])     = True 
    leqSymbol (Symbol (x:xs)) (Symbol (y:ys)) = proj (leqAChar x y) 
        (leqSymbol (Symbol xs) (Symbol ys))
    
    --write the one for symbol

    insert :: Symbol -> [Symbol] -> [Symbol]
    insert n [] = [n]
    insert n (h:t) = if leqSymbol n h then (n:h:t) else h:(insert n t)

    insertionSort :: [Symbol] -> [Symbol]
    insertionSort [] = []
    insertionSort (h:t) = insert h (insertionSort t)
    
    --prefined symbols until I get a quasiquoter or something
    color = Symbol [CC, CO, CL, CO, CR]
    position = Symbol [CP, CO, CS, CI, CT, CI, CO, CN]
    
    |]
      
-- Conversions to any from Integers
fromNat :: Nat -> Integer
fromNat Zero = 0
fromNat (Succ n) = (fromNat n) + 1

toNat :: Integer -> Nat
toNat 0         = Zero
toNat n | n > 0 = Succ (toNat (n - 1))
toNat _         = error "Converting negative to Nat"   
      
      
      
      
      
      
               
