α1 α2 α3 # α4
As the code stands, the generated parser is built using the buildExpressionParser facility of the Parsec parser library. Unfortunately, buildExpressionParser is only capable of handling expression languages with unary prefix, binary infix and unary postfix operators, meaning that we can't generate parsers for all calculi that can be defined with our language.
To fix this, I'm going to have to write a more general expression parser generator (hopefully using buildExpressionParser as a base) that can handle operators of arbitrary arity and fixity. Either that, restrict the system to only unary and binary operators which would make implementing some [conceivable] logics very difficult, if not impossible.
On the other hand, buildExpressionParser has greatly simplified the pattern handling code in the compiler. In our language (which is so simple as to not need a name), we define rules such as:
Resolve "a->b" to "~a" or "b".
The patterns (the bits in quote marks) are formulae using the operators of the calculus, with arbitrary alphabetic names for variables (which can stand for any sub-formula - we can make no distinction at this point between sub-formulae and propositions as I haven't got round to implementing that yet). Our compiler generates resolve (Impl a b) = Or [(Neg a), b]
Once we've parsed the pattern and generated a function, we get the pattern matching at run-time for free from Haskell.
1 comment:
This looks really neat. I don't really care about complicated n-ary operations where n > 3 (I'm partial to being able to define rules for ternary connectives, "until" coming to mind, of course.)
I'm especially keen on seeing the generality you've been able to achieve, and seeing how the code you write might inspire me (or others) into writing things that generate other sorts of proofs.
I'm looking forward to seeing code!
Post a Comment