Parsing a Formal Logic in Haskell












3















I have the following language I am trying to parse.



formula ::=  true  
| false
| var
| formula & formula
| ∀ var . formula
| (formula)

var ::= letter { letter | digit }*


I have been following this article on the Haskell wiki and have used Parsec combinators to create the following parser.



module LogicParser where

import System.IO
import Control.Monad
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Expr
import Text.ParserCombinators.Parsec.Language
import qualified Text.ParserCombinators.Parsec.Token as Token

-- Data Structures
data Formula = Var String
| TT
| FF
| Con Formula Formula
| Forall String Formula
deriving (Show)

-- Language Definition
lang :: LanguageDef st
lang =
emptyDef{ Token.identStart = letter
, Token.identLetter = alphaNum
, Token.opStart = oneOf "&."
, Token.opLetter = oneOf "&."
, Token.reservedOpNames = ["&", "."]
, Token.reservedNames = ["tt", "ff", "forall"]
}


-- Lexer for langauge
lexer =
Token.makeTokenParser lang


-- Trivial Parsers
identifier = Token.identifier lexer
keyword = Token.reserved lexer
op = Token.reservedOp lexer
roundBrackets = Token.parens lexer
whiteSpace = Token.whiteSpace lexer

-- Main Parser, takes care of trailing whitespaces
formulaParser :: Parser Formula
formulaParser = whiteSpace >> formula

-- Parsing Formulas
formula :: Parser Formula
formula = conFormula
<|> formulaTerm
<|> forallFormula

-- Term in a Formula
formulaTerm :: Parser Formula
formulaTerm = roundBrackets formula
<|> ttFormula
<|> ffFormula
<|> varFormula

-- Conjunction
conFormula :: Parser Formula
conFormula =
buildExpressionParser [[Infix (op "&" >> return Con) AssocLeft]] formula

-- Truth
ttFormula :: Parser Formula
ttFormula = keyword "tt" >> return TT

-- Falsehood
ffFormula :: Parser Formula
ffFormula = keyword "ff" >> return FF

-- Variable
varFormula :: Parser Formula
varFormula =
do var <- identifier
return $ Var var

-- Universal Statement
forallFormula :: Parser Formula
forallFormula =
do keyword "forall"
x <- identifier
op "."
phi <- formulaTerm
return $ Forall x phi

-- For running runghc
calculate :: String -> String
calculate s =
case ret of
Left e -> "Error: " ++ (show e)
Right n -> "Interpreted as: " ++ (show n)
where
ret = parse formulaParser "" s

main :: IO ()
main = interact (unlines . (map calculate) . lines)


The problem is the & operator, I am trying to model it on how the article parses expressions, using the Infix function and passing it a list of operators and a parser to parse terms. However, the parser is not behaving as desired and I can't work out why. Here are some examples of desired behaviour:



true                         -- parsing -->      TT
true & false -- parsing --> Con TT FF
true & (true & false) -- parsing --> Con TT (Con TT FF)
forall x . false & true -- parsing --> Con (Forall "x" FF) TT


However currently the parser is producing no output. I appreciate any assistance.










share|improve this question

























  • @mschmidt Thanks, I'll fix that.

    – Luke Collins
    Nov 20 '18 at 13:03











  • When I try to parse, I get no output at all (I think it hangs/goes into an infinite loop). But if I remove conformula from the parser formula (i.e. if I do formula = formulaTerm <|> varFormula <|> forallFormula), the parser works as desired.

    – Luke Collins
    Nov 20 '18 at 13:16











  • Ok, I don't think, I know it goes into an infinite loop (it slowed down my computer after a while). Here's the output.

    – Luke Collins
    Nov 20 '18 at 13:26
















3















I have the following language I am trying to parse.



formula ::=  true  
| false
| var
| formula & formula
| ∀ var . formula
| (formula)

var ::= letter { letter | digit }*


I have been following this article on the Haskell wiki and have used Parsec combinators to create the following parser.



module LogicParser where

import System.IO
import Control.Monad
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Expr
import Text.ParserCombinators.Parsec.Language
import qualified Text.ParserCombinators.Parsec.Token as Token

-- Data Structures
data Formula = Var String
| TT
| FF
| Con Formula Formula
| Forall String Formula
deriving (Show)

-- Language Definition
lang :: LanguageDef st
lang =
emptyDef{ Token.identStart = letter
, Token.identLetter = alphaNum
, Token.opStart = oneOf "&."
, Token.opLetter = oneOf "&."
, Token.reservedOpNames = ["&", "."]
, Token.reservedNames = ["tt", "ff", "forall"]
}


-- Lexer for langauge
lexer =
Token.makeTokenParser lang


-- Trivial Parsers
identifier = Token.identifier lexer
keyword = Token.reserved lexer
op = Token.reservedOp lexer
roundBrackets = Token.parens lexer
whiteSpace = Token.whiteSpace lexer

-- Main Parser, takes care of trailing whitespaces
formulaParser :: Parser Formula
formulaParser = whiteSpace >> formula

-- Parsing Formulas
formula :: Parser Formula
formula = conFormula
<|> formulaTerm
<|> forallFormula

-- Term in a Formula
formulaTerm :: Parser Formula
formulaTerm = roundBrackets formula
<|> ttFormula
<|> ffFormula
<|> varFormula

-- Conjunction
conFormula :: Parser Formula
conFormula =
buildExpressionParser [[Infix (op "&" >> return Con) AssocLeft]] formula

-- Truth
ttFormula :: Parser Formula
ttFormula = keyword "tt" >> return TT

-- Falsehood
ffFormula :: Parser Formula
ffFormula = keyword "ff" >> return FF

-- Variable
varFormula :: Parser Formula
varFormula =
do var <- identifier
return $ Var var

-- Universal Statement
forallFormula :: Parser Formula
forallFormula =
do keyword "forall"
x <- identifier
op "."
phi <- formulaTerm
return $ Forall x phi

-- For running runghc
calculate :: String -> String
calculate s =
case ret of
Left e -> "Error: " ++ (show e)
Right n -> "Interpreted as: " ++ (show n)
where
ret = parse formulaParser "" s

main :: IO ()
main = interact (unlines . (map calculate) . lines)


The problem is the & operator, I am trying to model it on how the article parses expressions, using the Infix function and passing it a list of operators and a parser to parse terms. However, the parser is not behaving as desired and I can't work out why. Here are some examples of desired behaviour:



true                         -- parsing -->      TT
true & false -- parsing --> Con TT FF
true & (true & false) -- parsing --> Con TT (Con TT FF)
forall x . false & true -- parsing --> Con (Forall "x" FF) TT


However currently the parser is producing no output. I appreciate any assistance.










share|improve this question

























  • @mschmidt Thanks, I'll fix that.

    – Luke Collins
    Nov 20 '18 at 13:03











  • When I try to parse, I get no output at all (I think it hangs/goes into an infinite loop). But if I remove conformula from the parser formula (i.e. if I do formula = formulaTerm <|> varFormula <|> forallFormula), the parser works as desired.

    – Luke Collins
    Nov 20 '18 at 13:16











  • Ok, I don't think, I know it goes into an infinite loop (it slowed down my computer after a while). Here's the output.

    – Luke Collins
    Nov 20 '18 at 13:26














3












3








3


2






I have the following language I am trying to parse.



formula ::=  true  
| false
| var
| formula & formula
| ∀ var . formula
| (formula)

var ::= letter { letter | digit }*


I have been following this article on the Haskell wiki and have used Parsec combinators to create the following parser.



module LogicParser where

import System.IO
import Control.Monad
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Expr
import Text.ParserCombinators.Parsec.Language
import qualified Text.ParserCombinators.Parsec.Token as Token

-- Data Structures
data Formula = Var String
| TT
| FF
| Con Formula Formula
| Forall String Formula
deriving (Show)

-- Language Definition
lang :: LanguageDef st
lang =
emptyDef{ Token.identStart = letter
, Token.identLetter = alphaNum
, Token.opStart = oneOf "&."
, Token.opLetter = oneOf "&."
, Token.reservedOpNames = ["&", "."]
, Token.reservedNames = ["tt", "ff", "forall"]
}


-- Lexer for langauge
lexer =
Token.makeTokenParser lang


-- Trivial Parsers
identifier = Token.identifier lexer
keyword = Token.reserved lexer
op = Token.reservedOp lexer
roundBrackets = Token.parens lexer
whiteSpace = Token.whiteSpace lexer

-- Main Parser, takes care of trailing whitespaces
formulaParser :: Parser Formula
formulaParser = whiteSpace >> formula

-- Parsing Formulas
formula :: Parser Formula
formula = conFormula
<|> formulaTerm
<|> forallFormula

-- Term in a Formula
formulaTerm :: Parser Formula
formulaTerm = roundBrackets formula
<|> ttFormula
<|> ffFormula
<|> varFormula

-- Conjunction
conFormula :: Parser Formula
conFormula =
buildExpressionParser [[Infix (op "&" >> return Con) AssocLeft]] formula

-- Truth
ttFormula :: Parser Formula
ttFormula = keyword "tt" >> return TT

-- Falsehood
ffFormula :: Parser Formula
ffFormula = keyword "ff" >> return FF

-- Variable
varFormula :: Parser Formula
varFormula =
do var <- identifier
return $ Var var

-- Universal Statement
forallFormula :: Parser Formula
forallFormula =
do keyword "forall"
x <- identifier
op "."
phi <- formulaTerm
return $ Forall x phi

-- For running runghc
calculate :: String -> String
calculate s =
case ret of
Left e -> "Error: " ++ (show e)
Right n -> "Interpreted as: " ++ (show n)
where
ret = parse formulaParser "" s

main :: IO ()
main = interact (unlines . (map calculate) . lines)


The problem is the & operator, I am trying to model it on how the article parses expressions, using the Infix function and passing it a list of operators and a parser to parse terms. However, the parser is not behaving as desired and I can't work out why. Here are some examples of desired behaviour:



true                         -- parsing -->      TT
true & false -- parsing --> Con TT FF
true & (true & false) -- parsing --> Con TT (Con TT FF)
forall x . false & true -- parsing --> Con (Forall "x" FF) TT


However currently the parser is producing no output. I appreciate any assistance.










share|improve this question
















I have the following language I am trying to parse.



formula ::=  true  
| false
| var
| formula & formula
| ∀ var . formula
| (formula)

var ::= letter { letter | digit }*


I have been following this article on the Haskell wiki and have used Parsec combinators to create the following parser.



module LogicParser where

import System.IO
import Control.Monad
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Expr
import Text.ParserCombinators.Parsec.Language
import qualified Text.ParserCombinators.Parsec.Token as Token

-- Data Structures
data Formula = Var String
| TT
| FF
| Con Formula Formula
| Forall String Formula
deriving (Show)

-- Language Definition
lang :: LanguageDef st
lang =
emptyDef{ Token.identStart = letter
, Token.identLetter = alphaNum
, Token.opStart = oneOf "&."
, Token.opLetter = oneOf "&."
, Token.reservedOpNames = ["&", "."]
, Token.reservedNames = ["tt", "ff", "forall"]
}


-- Lexer for langauge
lexer =
Token.makeTokenParser lang


-- Trivial Parsers
identifier = Token.identifier lexer
keyword = Token.reserved lexer
op = Token.reservedOp lexer
roundBrackets = Token.parens lexer
whiteSpace = Token.whiteSpace lexer

-- Main Parser, takes care of trailing whitespaces
formulaParser :: Parser Formula
formulaParser = whiteSpace >> formula

-- Parsing Formulas
formula :: Parser Formula
formula = conFormula
<|> formulaTerm
<|> forallFormula

-- Term in a Formula
formulaTerm :: Parser Formula
formulaTerm = roundBrackets formula
<|> ttFormula
<|> ffFormula
<|> varFormula

-- Conjunction
conFormula :: Parser Formula
conFormula =
buildExpressionParser [[Infix (op "&" >> return Con) AssocLeft]] formula

-- Truth
ttFormula :: Parser Formula
ttFormula = keyword "tt" >> return TT

-- Falsehood
ffFormula :: Parser Formula
ffFormula = keyword "ff" >> return FF

-- Variable
varFormula :: Parser Formula
varFormula =
do var <- identifier
return $ Var var

-- Universal Statement
forallFormula :: Parser Formula
forallFormula =
do keyword "forall"
x <- identifier
op "."
phi <- formulaTerm
return $ Forall x phi

-- For running runghc
calculate :: String -> String
calculate s =
case ret of
Left e -> "Error: " ++ (show e)
Right n -> "Interpreted as: " ++ (show n)
where
ret = parse formulaParser "" s

main :: IO ()
main = interact (unlines . (map calculate) . lines)


The problem is the & operator, I am trying to model it on how the article parses expressions, using the Infix function and passing it a list of operators and a parser to parse terms. However, the parser is not behaving as desired and I can't work out why. Here are some examples of desired behaviour:



true                         -- parsing -->      TT
true & false -- parsing --> Con TT FF
true & (true & false) -- parsing --> Con TT (Con TT FF)
forall x . false & true -- parsing --> Con (Forall "x" FF) TT


However currently the parser is producing no output. I appreciate any assistance.







parsing haskell parsec






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 '18 at 13:01







Luke Collins

















asked Nov 20 '18 at 12:41









Luke CollinsLuke Collins

622622




622622













  • @mschmidt Thanks, I'll fix that.

    – Luke Collins
    Nov 20 '18 at 13:03











  • When I try to parse, I get no output at all (I think it hangs/goes into an infinite loop). But if I remove conformula from the parser formula (i.e. if I do formula = formulaTerm <|> varFormula <|> forallFormula), the parser works as desired.

    – Luke Collins
    Nov 20 '18 at 13:16











  • Ok, I don't think, I know it goes into an infinite loop (it slowed down my computer after a while). Here's the output.

    – Luke Collins
    Nov 20 '18 at 13:26



















  • @mschmidt Thanks, I'll fix that.

    – Luke Collins
    Nov 20 '18 at 13:03











  • When I try to parse, I get no output at all (I think it hangs/goes into an infinite loop). But if I remove conformula from the parser formula (i.e. if I do formula = formulaTerm <|> varFormula <|> forallFormula), the parser works as desired.

    – Luke Collins
    Nov 20 '18 at 13:16











  • Ok, I don't think, I know it goes into an infinite loop (it slowed down my computer after a while). Here's the output.

    – Luke Collins
    Nov 20 '18 at 13:26

















@mschmidt Thanks, I'll fix that.

– Luke Collins
Nov 20 '18 at 13:03





@mschmidt Thanks, I'll fix that.

– Luke Collins
Nov 20 '18 at 13:03













When I try to parse, I get no output at all (I think it hangs/goes into an infinite loop). But if I remove conformula from the parser formula (i.e. if I do formula = formulaTerm <|> varFormula <|> forallFormula), the parser works as desired.

– Luke Collins
Nov 20 '18 at 13:16





When I try to parse, I get no output at all (I think it hangs/goes into an infinite loop). But if I remove conformula from the parser formula (i.e. if I do formula = formulaTerm <|> varFormula <|> forallFormula), the parser works as desired.

– Luke Collins
Nov 20 '18 at 13:16













Ok, I don't think, I know it goes into an infinite loop (it slowed down my computer after a while). Here's the output.

– Luke Collins
Nov 20 '18 at 13:26





Ok, I don't think, I know it goes into an infinite loop (it slowed down my computer after a while). Here's the output.

– Luke Collins
Nov 20 '18 at 13:26












2 Answers
2






active

oldest

votes


















1














I think I managed to fix the problem by rephrasing the grammar, and conjunction is still left-associative:



formula :: Parser Formula
formula = conFormula
<|> formulaTerm

formulaTerm :: Parser Formula
formulaTerm = roundBrackets formula
<|> ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula

conFormula :: Parser Formula
conFormula =
buildExpressionParser [[Infix (op "&" >> return Con) AssocLeft]] formulaTerm


This parsed the following successfully.
enter image description here






share|improve this answer
























  • Looks OK for me, since it successfully parsed the tt & ff & tt. I never tried to use buildExpressionParser, but the trick is to parse for terms within the conjunction, not for formulas.

    – mschmidt
    Nov 20 '18 at 23:07











  • Since conFormula can already match a single formulaTern, you don't need formulaTerm as an alternative in term.

    – sepp2k
    Nov 20 '18 at 23:50



















0














The problem in your code is, that you try to parse a formula for which the first attempt is to parse a formulaCon. This then first tries to parse a formula, i.e. you create an infinite recursion without consuming any input.



To resolve this, you have to structure your grammar. Define your terms like this (note that all these terms consume some input before doing a recursion back to formula):



formulaTerm = ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula
<|> roundBrackets formula

forallFormula = do
keyword "forall"
x <- identifier
op "."
phi <- formula
return $ Forall x phi


A formula is then either a single term or a conjunction consisting of term, an operator, and another formula. To ensure that all input is parsed, first try to parse a conjunction and - if that fails - parse a single term:



formula = (try formulaCon) <|> formulaTerm


Finally a formulaCon can be parsed like this:



formulaCon = do
f1 <- formulaTerm
op "&"
f2 <- formula
return $ Con f1 f2


The drawback with this solution is that conjunctions are now right associative.






share|improve this answer
























  • I like this solution, although I'm not sure why we need a try for the formulaCon. I think I managed to fix it by rephrasing the grammar, preserving left-associativity. Could you take a look at it and check whether it's correct? I posted it as an answer.

    – Luke Collins
    Nov 20 '18 at 22:13











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393220%2fparsing-a-formal-logic-in-haskell%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














I think I managed to fix the problem by rephrasing the grammar, and conjunction is still left-associative:



formula :: Parser Formula
formula = conFormula
<|> formulaTerm

formulaTerm :: Parser Formula
formulaTerm = roundBrackets formula
<|> ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula

conFormula :: Parser Formula
conFormula =
buildExpressionParser [[Infix (op "&" >> return Con) AssocLeft]] formulaTerm


This parsed the following successfully.
enter image description here






share|improve this answer
























  • Looks OK for me, since it successfully parsed the tt & ff & tt. I never tried to use buildExpressionParser, but the trick is to parse for terms within the conjunction, not for formulas.

    – mschmidt
    Nov 20 '18 at 23:07











  • Since conFormula can already match a single formulaTern, you don't need formulaTerm as an alternative in term.

    – sepp2k
    Nov 20 '18 at 23:50
















1














I think I managed to fix the problem by rephrasing the grammar, and conjunction is still left-associative:



formula :: Parser Formula
formula = conFormula
<|> formulaTerm

formulaTerm :: Parser Formula
formulaTerm = roundBrackets formula
<|> ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula

conFormula :: Parser Formula
conFormula =
buildExpressionParser [[Infix (op "&" >> return Con) AssocLeft]] formulaTerm


This parsed the following successfully.
enter image description here






share|improve this answer
























  • Looks OK for me, since it successfully parsed the tt & ff & tt. I never tried to use buildExpressionParser, but the trick is to parse for terms within the conjunction, not for formulas.

    – mschmidt
    Nov 20 '18 at 23:07











  • Since conFormula can already match a single formulaTern, you don't need formulaTerm as an alternative in term.

    – sepp2k
    Nov 20 '18 at 23:50














1












1








1







I think I managed to fix the problem by rephrasing the grammar, and conjunction is still left-associative:



formula :: Parser Formula
formula = conFormula
<|> formulaTerm

formulaTerm :: Parser Formula
formulaTerm = roundBrackets formula
<|> ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula

conFormula :: Parser Formula
conFormula =
buildExpressionParser [[Infix (op "&" >> return Con) AssocLeft]] formulaTerm


This parsed the following successfully.
enter image description here






share|improve this answer













I think I managed to fix the problem by rephrasing the grammar, and conjunction is still left-associative:



formula :: Parser Formula
formula = conFormula
<|> formulaTerm

formulaTerm :: Parser Formula
formulaTerm = roundBrackets formula
<|> ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula

conFormula :: Parser Formula
conFormula =
buildExpressionParser [[Infix (op "&" >> return Con) AssocLeft]] formulaTerm


This parsed the following successfully.
enter image description here







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 20 '18 at 22:11









Luke CollinsLuke Collins

622622




622622













  • Looks OK for me, since it successfully parsed the tt & ff & tt. I never tried to use buildExpressionParser, but the trick is to parse for terms within the conjunction, not for formulas.

    – mschmidt
    Nov 20 '18 at 23:07











  • Since conFormula can already match a single formulaTern, you don't need formulaTerm as an alternative in term.

    – sepp2k
    Nov 20 '18 at 23:50



















  • Looks OK for me, since it successfully parsed the tt & ff & tt. I never tried to use buildExpressionParser, but the trick is to parse for terms within the conjunction, not for formulas.

    – mschmidt
    Nov 20 '18 at 23:07











  • Since conFormula can already match a single formulaTern, you don't need formulaTerm as an alternative in term.

    – sepp2k
    Nov 20 '18 at 23:50

















Looks OK for me, since it successfully parsed the tt & ff & tt. I never tried to use buildExpressionParser, but the trick is to parse for terms within the conjunction, not for formulas.

– mschmidt
Nov 20 '18 at 23:07





Looks OK for me, since it successfully parsed the tt & ff & tt. I never tried to use buildExpressionParser, but the trick is to parse for terms within the conjunction, not for formulas.

– mschmidt
Nov 20 '18 at 23:07













Since conFormula can already match a single formulaTern, you don't need formulaTerm as an alternative in term.

– sepp2k
Nov 20 '18 at 23:50





Since conFormula can already match a single formulaTern, you don't need formulaTerm as an alternative in term.

– sepp2k
Nov 20 '18 at 23:50













0














The problem in your code is, that you try to parse a formula for which the first attempt is to parse a formulaCon. This then first tries to parse a formula, i.e. you create an infinite recursion without consuming any input.



To resolve this, you have to structure your grammar. Define your terms like this (note that all these terms consume some input before doing a recursion back to formula):



formulaTerm = ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula
<|> roundBrackets formula

forallFormula = do
keyword "forall"
x <- identifier
op "."
phi <- formula
return $ Forall x phi


A formula is then either a single term or a conjunction consisting of term, an operator, and another formula. To ensure that all input is parsed, first try to parse a conjunction and - if that fails - parse a single term:



formula = (try formulaCon) <|> formulaTerm


Finally a formulaCon can be parsed like this:



formulaCon = do
f1 <- formulaTerm
op "&"
f2 <- formula
return $ Con f1 f2


The drawback with this solution is that conjunctions are now right associative.






share|improve this answer
























  • I like this solution, although I'm not sure why we need a try for the formulaCon. I think I managed to fix it by rephrasing the grammar, preserving left-associativity. Could you take a look at it and check whether it's correct? I posted it as an answer.

    – Luke Collins
    Nov 20 '18 at 22:13
















0














The problem in your code is, that you try to parse a formula for which the first attempt is to parse a formulaCon. This then first tries to parse a formula, i.e. you create an infinite recursion without consuming any input.



To resolve this, you have to structure your grammar. Define your terms like this (note that all these terms consume some input before doing a recursion back to formula):



formulaTerm = ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula
<|> roundBrackets formula

forallFormula = do
keyword "forall"
x <- identifier
op "."
phi <- formula
return $ Forall x phi


A formula is then either a single term or a conjunction consisting of term, an operator, and another formula. To ensure that all input is parsed, first try to parse a conjunction and - if that fails - parse a single term:



formula = (try formulaCon) <|> formulaTerm


Finally a formulaCon can be parsed like this:



formulaCon = do
f1 <- formulaTerm
op "&"
f2 <- formula
return $ Con f1 f2


The drawback with this solution is that conjunctions are now right associative.






share|improve this answer
























  • I like this solution, although I'm not sure why we need a try for the formulaCon. I think I managed to fix it by rephrasing the grammar, preserving left-associativity. Could you take a look at it and check whether it's correct? I posted it as an answer.

    – Luke Collins
    Nov 20 '18 at 22:13














0












0








0







The problem in your code is, that you try to parse a formula for which the first attempt is to parse a formulaCon. This then first tries to parse a formula, i.e. you create an infinite recursion without consuming any input.



To resolve this, you have to structure your grammar. Define your terms like this (note that all these terms consume some input before doing a recursion back to formula):



formulaTerm = ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula
<|> roundBrackets formula

forallFormula = do
keyword "forall"
x <- identifier
op "."
phi <- formula
return $ Forall x phi


A formula is then either a single term or a conjunction consisting of term, an operator, and another formula. To ensure that all input is parsed, first try to parse a conjunction and - if that fails - parse a single term:



formula = (try formulaCon) <|> formulaTerm


Finally a formulaCon can be parsed like this:



formulaCon = do
f1 <- formulaTerm
op "&"
f2 <- formula
return $ Con f1 f2


The drawback with this solution is that conjunctions are now right associative.






share|improve this answer













The problem in your code is, that you try to parse a formula for which the first attempt is to parse a formulaCon. This then first tries to parse a formula, i.e. you create an infinite recursion without consuming any input.



To resolve this, you have to structure your grammar. Define your terms like this (note that all these terms consume some input before doing a recursion back to formula):



formulaTerm = ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula
<|> roundBrackets formula

forallFormula = do
keyword "forall"
x <- identifier
op "."
phi <- formula
return $ Forall x phi


A formula is then either a single term or a conjunction consisting of term, an operator, and another formula. To ensure that all input is parsed, first try to parse a conjunction and - if that fails - parse a single term:



formula = (try formulaCon) <|> formulaTerm


Finally a formulaCon can be parsed like this:



formulaCon = do
f1 <- formulaTerm
op "&"
f2 <- formula
return $ Con f1 f2


The drawback with this solution is that conjunctions are now right associative.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 20 '18 at 21:53









mschmidtmschmidt

1,96941019




1,96941019













  • I like this solution, although I'm not sure why we need a try for the formulaCon. I think I managed to fix it by rephrasing the grammar, preserving left-associativity. Could you take a look at it and check whether it's correct? I posted it as an answer.

    – Luke Collins
    Nov 20 '18 at 22:13



















  • I like this solution, although I'm not sure why we need a try for the formulaCon. I think I managed to fix it by rephrasing the grammar, preserving left-associativity. Could you take a look at it and check whether it's correct? I posted it as an answer.

    – Luke Collins
    Nov 20 '18 at 22:13

















I like this solution, although I'm not sure why we need a try for the formulaCon. I think I managed to fix it by rephrasing the grammar, preserving left-associativity. Could you take a look at it and check whether it's correct? I posted it as an answer.

– Luke Collins
Nov 20 '18 at 22:13





I like this solution, although I'm not sure why we need a try for the formulaCon. I think I managed to fix it by rephrasing the grammar, preserving left-associativity. Could you take a look at it and check whether it's correct? I posted it as an answer.

– Luke Collins
Nov 20 '18 at 22:13


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393220%2fparsing-a-formal-logic-in-haskell%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Guess what letter conforming each word

Port of Spain

Run scheduled task as local user group (not BUILTIN)