Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

Logic of "all" + verbs + relative clauses, for a class at Indiana University

Views: 6871
1
-- There are "2" versions of a bunch of commands
2
-- Right now, those are the only ones that are needed.
3
-- The rest should be dropped at some point.
4
5
module SyllogisticInference where
6
7
import Data.List
8
import Control.Monad
9
import ARC/Syntax2
10
import ARC/ProofTreeNumbers
11
import ARC/ExampleSentences
12
import ARC/ExampleRules
13
import ARC/FrontEnd
14
import Data.List (transpose, intercalate)
15
16
get1 (a,b,c) = a
17
get2 (a,b,c) = b
18
get3 (a,b,c) = c
19
20
get1Of4 (a,b,c,d) = a
21
get2Of4 (a,b,c,d) = b
22
get3Of4(a,b,c,d) = c
23
get4Of4(a,b,c,d) = d
24
25
--firstHelp :: a -> [a] -> [[a]]
26
firstHelp x [] = []
27
firstHelp x (y:ytail) = (x,y) : firstHelp x ytail
28
29
--secondHelp :: [a] -> [a] -> [[[a]]]
30
secondHelp list ys = map (\ x -> firstHelp x ys) list
31
32
allFns list1 list2 = sequence $ (secondHelp list1 list2)
33
34
{- not needed, I think
35
lookfor key ((a,b):abs)
36
| key == a = b
37
-}
38
39
emptyAsDefault :: Maybe [a] -> [a]
40
emptyAsDefault mx = case mx of
41
Nothing -> []
42
Just xy -> xy
43
zeroAsDefault :: Maybe Int -> Int
44
zeroAsDefault mx = case mx of
45
Nothing -> 0
46
Just xy -> xy
47
48
49
findD (Sent d t1 t2) = d
50
g1 (Sent d t1 t2) = t1
51
g2 (Sent d t1 t2) = t2
52
53
54
addAssumptionAsReason :: Sent -> (Sent, String, [Sent])
55
addAssumptionAsReason s = (s, "assumption", [])
56
addReasonsToOriginal :: [Sent] -> [(Sent,String,[Sent])]
57
addReasonsToOriginal = map addAssumptionAsReason
58
59
varsInConclusion :: Rule -> [Term]
60
varsInConclusion r = nub [g1 $ conclusion r, g2 $ conclusion r]
61
62
premiseExtractPairs :: Rule -> [(Term,Term)]
63
premiseExtractPairs r =
64
let f (Sent d t1 t2) = (t1, t2)
65
in map f $ premises r
66
67
varsInPremises :: Rule -> [Term]
68
varsInPremises r = concat [[a,b] | (a,b) <- premiseExtractPairs r]
69
70
extras :: Rule -> [Term]
71
extras r = (varsInConclusion r) \\ (varsInPremises r)
72
73
-- I am not sure if 'extras' just above is used. But the variants below are used.
74
75
extracnsInRule r = nub $ (cnsIn (conclusion r) ) \\ (concatMap cnsIn (premises r))
76
extraVerbsInRule r = nub $ (verbsIn (conclusion r) ) \\ (concatMap verbsIn (premises r))
77
78
fixDuplicates xs = nubBy conclusionsMatch xs
79
where conclusionsMatch ys zs =
80
get1 ys == get1 zs
81
82
--------------------------- here is where the main part of the code starts
83
84
buildPairOfSubs :: Sent -> [Sent] -> [(Sent, Maybe [(Term, Term)], Maybe [(PV, PV)])]
85
buildPairOfSubs sent sList = [(s, buildTermSub sent s,buildPVSub sent s) | s <- sList, Nothing /= buildTermSub sent s, Nothing /= buildPVSub sent s ]
86
87
ruleToPairOfSubs :: Rule -> [Sent] -> [[(Sent, Maybe [(Term, Term)], Maybe [(PV, PV)])]]
88
ruleToPairOfSubs rule sList = map (\ x -> buildPairOfSubs x sList) (premises rule)
89
90
applicableInstances :: [Sent] -> Rule -> [([Sent], [(Term, Term)], [(PV, PV)])]
91
applicableInstances sList rule =
92
let
93
jj = sequence $ (ruleToPairOfSubs rule sList)
94
checkerUnary x = foldl combineStructures (Just []) (map get2 x)
95
checkerBinary x = foldl combineStructures (Just []) (map get3 x)
96
in
97
[((map get1 x), (emptyAsDefault $ checkerUnary x), (emptyAsDefault $ checkerBinary x)) | x <- jj, Nothing /= checkerUnary x, Nothing /= checkerBinary x]
98
99
100
extraReconciliationVerbs rule sList = if extraVerbsInRule rule == [] then (applicableInstances sList rule ) else
101
let
102
above = [[((PV Pos x),(PV Pos y))] | x <- (extraVerbsInRule rule), y<- verblistNotVars]
103
in
104
concatMap (\ y -> (map (\ x -> (get1 x, get2 x , (get3 x ++ y))) (applicableInstances sList rule))) above
105
-- the 'above' above had y <- verblistNotVars rather than w
106
107
108
eVerbs rule sList vList = if extraVerbsInRule rule == [] then (applicableInstances sList rule ) else
109
let
110
above = [[((PV Pos x),(PV Pos y))] | x <- (extraVerbsInRule rule), y<- vList ]
111
in
112
concatMap (\ y -> (map (\ x -> (get1 x, get2 x , (get3 x ++ y))) (applicableInstances sList rule))) above
113
114
115
116
extraReconciliationCNs rule sList = if extracnsInRule rule == [] then (extraReconciliationVerbs rule sList) else
117
let
118
useThese = nub $ concatMap cnsIn sList
119
firstSet = [CNasTerm (PCN Pos cn1 ) | cn1 <- extracnsInRule rule]
120
secondSet = [CNasTerm (PCN Pos cn2 ) | cn2 <- useThese]
121
firstSetNeg = [CNasTerm (PCN Neg cn1 ) | cn1 <- extracnsInRule rule]
122
secondSetNeg = [CNasTerm (PCN Neg cn2 ) | cn2 <- useThese]
123
tv = or $ map (hasNegativeMarker . pCNsIn) $ concatMap subterms sList
124
extras = if tv then allFns firstSet secondSetNeg else [ ]
125
subs = (allFns firstSet secondSet) ++ extras
126
in
127
concatMap (\ y -> (map (\ x -> (get1 x, (get2 x ++ y) , get3 x)) (extraReconciliationVerbs rule sList ))) subs
128
129
130
extraCNs rule sList cnsToInclude verbsToInclude = if extracnsInRule rule == [] then (eVerbs rule sList verbsToInclude) else
131
let
132
useThese = cnsToInclude
133
firstSet = [CNasTerm (PCN Pos cn1 ) | cn1 <- extracnsInRule rule]
134
secondSet = [CNasTerm (PCN Pos cn2 ) | cn2 <- useThese]
135
firstSetNeg = [CNasTerm (PCN Neg cn1 ) | cn1 <- extracnsInRule rule]
136
secondSetNeg = [CNasTerm (PCN Neg cn2 ) | cn2 <- useThese]
137
tv = or $ map (hasNegativeMarker . pCNsIn) $ concatMap subterms sList
138
extras = if tv then allFns firstSet secondSetNeg else [ ]
139
subs = (allFns firstSet secondSet) ++ extras
140
in
141
concatMap (\ y -> (map (\ x -> (get1 x, (get2 x ++ y) , get3 x)) (extraReconciliationVerbs rule sList ))) subs
142
143
144
render rule item =
145
let t = conclusion rule
146
u = spellOut t (get2 item) (get3 item)
147
in (u, (rulename rule), get1 item)
148
149
dropReasons = map get1
150
151
applyARule sList r = nub $ map (\ x -> render r x) (extraReconciliationCNs r sList)
152
153
154
applyARule2 sList r exCNs exVerbs = nub $ map (\ x -> render r x) (extraCNs r sList exCNs exVerbs)
155
156
157
applyAllRules2 sListWithReasons rl exCNs exVerbs=
158
let
159
z = dropReasons sListWithReasons
160
a = map (\ x -> applyARule2 z x exCNs exVerbs) rl
161
b = concat a
162
in
163
fixDuplicates $ sListWithReasons ++ b
164
165
166
applyAllRules sListWithReasons rl =
167
let
168
z = dropReasons sListWithReasons
169
a = map (applyARule z) rl
170
b = concat a
171
in
172
fixDuplicates $ sListWithReasons ++ b
173
174
175
type SentRule = (Sent,String)
176
--data PTree = T (Sent,String) [PTree] ---- for development purposes, this declaration was moved to ProofTreeNumbers.hs
177
-- deriving (Show, Eq)
178
179
180
181
ll phi stumpset =
182
if (get1 $ (stumpset !! 0)) == phi then (stumpset !! 0) else (ll phi (tail stumpset))
183
184
proofSearch phi stumpset =
185
T ((get1 a), (get2 a)) (map (\ x -> (proofSearch x stumpset)) (get3 a))
186
where a = ll phi stumpset
187
188
189
firstRepeat (x:y:rest) = if x == y then x else firstRepeat (y:rest)
190
191
allDerived :: [Sent] -> [Rule] -> [(Sent, RuleName, [Sent])]
192
allDerived noReasons rl = allDerivedUnderRepresentations noReasons rl
193
194
--allDerived2 :: [Sent] -> [Rule] -> [(Sent, RuleName, [Sent])]
195
allDerived2 noReasons rl exCNs exVerbs = allDerivedUnderRepresentations2 noReasons rl exCNs exVerbs
196
197
198
allDerivedUnderRepresentations noReasons rl= firstRepeat $ fixedPoint addReasons rl
199
where addReasons = addReasonsToOriginal noReasons
200
201
allDerivedUnderRepresentations2 noReasons rl exCNs exVerbs = firstRepeat $ fixedPoint2 addReasons rl exCNs exVerbs
202
where addReasons = addReasonsToOriginal noReasons
203
204
fixedPoint withReasons rl = withReasons : map (\ x -> applyAllRules x rl) (fixedPoint withReasons rl)
205
206
fixedPoint2 withReasons rl exCNs exVerbs =
207
withReasons : map (\ x -> applyAllRules2 x rl exCNs exVerbs) (fixedPoint2 withReasons rl exCNs exVerbs)
208
209
210
fullStory noReasonList ruleList = fullStoryUnderRepresentations (readSs noReasonList) ruleList
211
--- e.g. fullStory ["all skunks mammals", "some mammals non-chordates"] sdagger
212
213
--fullStoryUnderRepresentations :: AssumptionList -> [Rule] -> IO ()
214
fullStoryUnderRepresentations noReasonList ruleList = mapM_ print $ map get1 $ allDerivedUnderRepresentations noReasonList ruleList
215
216
modify outputList = map (\ x -> (get1 x, fst (get2 x), snd(get2 x), get3 x)) outputList
217
218
-- let stumpset = allDerived [s8,s12] sList
219
-- let phi = get1 $ stumpset !! 13
220
findProofByNumber n ch = mapM_ print $ modify . full_reverse . near . tree_reverse $ proofSearch (get1 (ch !! n)) ch
221
222
inconsistency stumpset =
223
let
224
q = map get1 stumpset
225
--qq = map principalDet q
226
in
227
dropWhile (\ s -> Contradiction /= principalDet s)q
228
229
-- relevantChunk is NOT USED!
230
231
relevantChunk phi gamma ruleList =
232
let
233
addReasons = addReasonsToOriginal gamma
234
bingo = fixedPoint addReasons ruleList
235
firstRepeatOrFind (x:y:rest)
236
| phi `elem` (map get1 x) = x
237
| (inconsistency x) /= [] = x
238
| x == y = x
239
| otherwise = firstRepeatOrFind (y:rest)
240
in firstRepeatOrFind bingo
241
242
followsUnderRepresentation phi gamma ruleList =
243
let
244
addReasons = addReasonsToOriginal gamma
245
bingo = fixedPoint2 addReasons ruleList (cnsIn phi) (concatMap verbsIn (gamma ++ [phi]))
246
firstRepeatOrFind (x:y:rest)
247
| phi `elem` (map get1 x) = do
248
putStrLn " "
249
putStrLn "The sentence follows, and here is a derivation in the given logic from the assumptions:"
250
putStrLn " "
251
mapM_ print $ modify . full_reverse $ near $ tree_reverse $ proofSearch phi x
252
putStrLn " "
253
| (inconsistency x) /= [] = do
254
putStrLn " "
255
putStrLn "As shown below, the list of assumptions is inconsistent, so every sentence follows."
256
putStrLn " "
257
mapM_ print $ modify . full_reverse $ near $ tree_reverse $ proofSearch (head $ (inconsistency x)) x
258
| x == y = do
259
putStrLn " "
260
putStrLn "The given sentence is not provable from the assumptions in the logic."
261
putStrLn " "
262
| otherwise = firstRepeatOrFind (y:rest)
263
in firstRepeatOrFind bingo
264
265
follows phi gamma ruleList = followsUnderRepresentation (readS phi) (readSs gamma) ruleList
266
267
findAProof :: String -> [String] -> [Rule] -> [(Int, Sent, RuleName, [Int])]
268
findAProof p g ruleList =
269
let
270
phi = readS p
271
gamma = readSs g
272
addReasons = addReasonsToOriginal gamma
273
bingo = fixedPoint addReasons ruleList
274
firstRepeatOrFind (x:y:rest)
275
| phi `elem` (map get1 x) = modify . full_reverse $ near $ tree_reverse $ proofSearch phi x
276
| (inconsistency x) /= [] = []
277
| x == y = []
278
| otherwise = firstRepeatOrFind (y:rest)
279
in firstRepeatOrFind bingo
280
281
282
-- based on https://stackoverflow.com/questions/5929377/format-list-output-in-haskell
283
-- a type for records
284
data ProofLine = ProofLine { line :: Int
285
, sentence :: Sent
286
, rule :: RuleName
287
, supports :: [Int] }
288
deriving Show
289
290
291
-- test data
292
{- test =
293
[ ProofLine 1 (readS "all skunks mammals") "assumption" []
294
, ProofLine 2 (readS "all mammals chordates") "assumption" [1]
295
, ProofLine 3 (readS "all skunks chordates") "barbara" [1,2]
296
]
297
-}
298
299
300
displayAProof p g ruleList =
301
putStrLn $ showTable [ ColDesc center " " left (show . line)
302
, ColDesc center " " left (show. sentence)
303
, ColDesc center " " left rule
304
, ColDesc center " " right (intercalate ", " . map show . supports)
305
] $ getReadyToDisplay p g ruleList
306
307
getReadyToDisplay p g ruleList = map (\k -> ProofLine {line= get1Of4 k, sentence=get2Of4 k, rule = get3Of4 k, supports = get4Of4 k}) $ findAProof p g ruleList
308
309
310
311
--- :set +s for timing
312
313
314
315
---- EXTRA STUFF TO TRY TO PRETTY-PRINT THE PROOFS IN 3 NICE COLUMNS
316
---- SO FAR, NO LUCK!
317
318
--import Data.List (transpose, intercalate)
319
320
321
322
showT cs ts =
323
let header = map colTitle cs
324
rows = [[colValue c t | c <- cs] | t <- ts]
325
widths = [maximum $ map length col | col <- transpose $ header : rows]
326
separator = intercalate "-+-" [replicate width '-' | width <- widths]
327
fillCols fill cols = intercalate " | " [fill c width col | (c, width, col) <- zip3 cs widths cols]
328
in
329
unlines $ fillCols colTitleFill header : separator : map (fillCols colValueFill) rows
330
331
332