This project introduces a custom-built compiler that interprets and optimizes first-order predicate logic through a new language called PREDLOG1. The language is written in UTF-8 and allows formal logical terms to be defined as readable and structured code.
The compiler follows a classical, multi-stage compilation pipeline:
- Lexical Analysis — Tokenizes the input (Scanner via Flex)
- Syntactic Analysis — Parses tokens into a syntax tree (Parser via Bison)
- Semantic Analysis — Checks for logical consistency and type rules
- Code Optimization — Improves structure and reduces redundancy
- Code Generation — Produces a compiled, internal representation
To compile and run the compiler, ensure the following tools are installed:
flex
bison
gcc
make
Once installed, build the compiler by running:
make
This will compile main.c
and output the executable. Use the compiled program by passing a PREDLOG1 source file as the first argument:
./compiler yourfile.predlog1
PREDLOG1 (Predicate Logic Level 1) is a domain-specific language designed for expressing first-order predicate logic in a structured and parseable syntax.
Use /* comment */
for single-line comments. Multiline comments must be split.
All symbols must be explicitly declared before usage:
Type | Syntax |
---|---|
Predicate | DECLARE PREDICATE <id> : <arity> |
Function | DECLARE FUNCTION <id> : <arity> |
Variable | DECLARE VARIABLE <id> : int |
<id>
: Name/identifier of the symbol<arity>
: Number of arguments
Logic Symbol | PREDLOG1 Equivalent |
---|---|
↔ | <-> |
→ | -> |
∨ | | |
∧ | & |
¬ | ~ |
∀ var | ALL[*var*] |
∃ var | EXIST[*var*] |
false | FALSE |
true | TRUE |
Both ALL[var]
and ALL [var]
are accepted syntaxes (same for EXIST
).
From highest to lowest:
- Function
- Predicate
- Quantifiers (∀, ∃)
- Negation (¬)
- Conjunction (∧)
- Disjunction (∨)
- Implication (→)
- Biconditional (↔)
/* Example PREDLOG1 */
DECLARE PREDICATE Buys : 2
DECLARE PREDICATE Pumpkin : 1
DECLARE PREDICATE Person : 1
DECLARE FUNCTION Eats : 2
DECLARE FUNCTION Carves : 2
DECLARE FUNCTION John : 0
DECLARE VARIABLE x : int
DECLARE VARIABLE y : int
EXIST[x] (Buys(John,x) & Pumpkin(x))
& ALL[x] ALL[y] (Buys(x,y) & Pumpkin(y) -> Eats(x,y) | Carves(x,y))
& ALL[x] (Person(x) -> ALL[y] (Pumpkin(y) -> ~Eats(x,y)))
& ~(Person(John) -> EXIST[x] Carves(John,x)) ;
This expresses a mix of existential and universal quantifiers, logical implications, conjunctions, and negations—all handled cleanly through the PREDLOG1 syntax.