-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLatex.hs
182 lines (165 loc) · 5.22 KB
/
Latex.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
{-# LANGUAGE OverloadedStrings, NoMonomorphismRestriction #-}
module Latex where
import CoreTypes
import SeqCal
import System.Timeout
import Control.Monad
import Data.Char
import Data.Set (Set)
import qualified Data.Set as S
import Text.LaTeX hiding ((|-),proof)
proofTree = env "prooftree"
axiom = comm1 "AxiomC"
unary = comm1 "UnaryInfC"
binary = comm1 "BinaryInfC"
rlabel = comm1 "RightLabel"
imp = comm0_ "rightarrow"
equiv = comm0_ "leftrightarrow"
neg = comm0_ "neg"
turnstile = math $ comm0_ "vdash"
conj = comm0_ "wedge"
disj = comm0_ "vee"
top = comm0_ "top"
bot = comm0_ "bot"
forAll = comm0_ "forall"
exists = comm0_ "exists"
lintercalate :: Monad m => LaTeX m -> [LaTeX m] -> LaTeX m
lintercalate t (a:a':as) = a >> t >> lintercalate t (a':as)
lintercalate _ [a] = a
lintercalate _ _ = ""
prettyV :: Monad m => Var -> LaTeX m
prettyV t = case t of
UVar v -> fromString v
GVar i xs -> math $ do
fromString $ '\'' : vars !! i
"_{"
lintercalate "," $ map (prettyV . MVar) xs
"}"
MVar v -> fromString $ meta !! v
where
vars = [1..] >>= flip replicateM ['a'..'z']
meta = map (('?' :) . map toUpper) vars
prettyT :: Monad m => Term -> LaTeX m
prettyT t = case t of
Var x -> prettyV x
Const c -> fromString c
App idnt terms -> do
fromString idnt
"("
lintercalate "," (map prettyT terms)
")"
lpretty :: Monad m => Formula -> LaTeX m
lpretty = pretty' 0
where
pretty' :: Monad m => Int -> Formula -> LaTeX m
pretty' i f = case f of
Imp a b -> paren i 2 $ do
pretty' 3 a
math $ imp
pretty' 1 b
Equiv a b -> paren i 2 $ do
pretty' 3 a
math $ equiv
pretty' 3 b
Neg a -> paren i 3 $ do
math $ neg
pretty' 2 a
Rel idnt terms | null terms -> fromString idnt
| otherwise -> do
fromString idnt
"("
lintercalate "," (map prettyT terms)
")"
Top -> math top
Bot -> math bot
Or a b -> paren i 1 $ do
pretty' 2 a
math $ disj
pretty' 2 b
And a b -> paren i 1 $ do
pretty' 2 a
math $ conj
pretty' 2 b
ForAll a b -> do
math $ forAll
prettyV a
"."
pretty' 2 b
Exists a b -> do
math $ exists
prettyV a
"."
pretty' 2 b
paren x y m | x >= y = do
"("
m
")"
| otherwise = m
(|-) :: Monad m => Ctx -> Ctx -> LaTeX m
(|-) gamma delta = do
lintercalate "," $ [ lpretty x | x <- S.toList $ ctxToSet gamma]
turnstile
lintercalate "," $ [ lpretty x | x <- S.toList $ ctxToSet delta]
buildTree :: Monad m => Deduction -> LaTeX m
buildTree = proofTree . tree'
where
tree' ded = case ded of
Intro gamma delta -> zero "Intro"
LBot gamma delta -> zero $ "L" >> math bot
RTop gamma delta -> zero $ "R" >> math top
RImp f1 f2 prf -> one prf $ "R" >> math imp
LImp f1 f2 prf1 prf2 -> two prf1 prf2 $ "L" >> math imp
REqu f1 f2 prf1 prf2 -> two prf1 prf2 $ "R" >> math equiv
LEqu f1 f2 prf1 prf2 -> two prf1 prf2 $ "L" >> math equiv
RNeg f prf -> one prf $ "R" >> math neg
LNeg f prf -> one prf $ "L" >> math neg
RAnd f1 f2 prf1 prf2 -> two prf1 prf2 $ "R" >> math conj
LAnd f1 f2 prf -> one prf $ "L" >> math conj
ROr f1 f2 prf -> one prf $ "R" >> math disj
LOr f1 f2 prf1 prf2 -> two prf1 prf2 $ "L" >> math disj
RForAll f _ prf -> one prf $ "R" >> math forAll
LForAll f _ prf -> one prf $ "L" >> math forAll
RExists f _ prf -> one prf $ "R" >> math exists
LExists f _ prf -> one prf $ "L" >> math exists
where
zero lab = do
axiom ""
rlabel lab
unary (g |- d)
one prf lab = do
tree' prf
rlabel lab
unary (g |- d)
two prf1 prf2 lab = do
tree' prf1
tree' prf2
rlabel lab
binary (g |- d)
(g,d) = build ded
proof :: Monad m => Deduction -> LaTeX m
proof dd = do
documentclass [] article
usepackage [] "bussproofs"
usepackage [] "rotating"
usepackage [] "fullpage"
usepackage ["paperwidth=20in"] "geometry"
author "Solverine"
title "Proof"
date ""
-- comm0_ "setlength{\\textwidth}{520pt}"
-- comm0_ "special{papersize=2100mm,2970mm}"
document $ do
-- maketitle
{-comm1 "tiny" $ -} {-env "sidewaysfigure" $-} buildTree dd
createProof :: FilePath -> Formula -> IO ()
createProof filePath ff = do
res <- timeout 100000 $ case testFormula ff of
Just dd -> createProofFromDeduction filePath dd >> return True
Nothing -> return False
case res of
Just True -> putStrLn "proved ψ(`∇´)ψ"
Just False -> putStrLn "couldn't prove (><)"
Nothing -> putStrLn "timeout T_T"
createProofFromDeduction :: FilePath -> Deduction -> IO ()
createProofFromDeduction filePath dd =
writeFile filePath . unlines $ render (proof dd)