(* ************************************************************************* *)
(* *)
(* natural-deduction: a basic proof assistant for natural deduction in *)
(* first-order logic. *)
(* *)
(* Copyright (C) 2026 Eric Johannesson, eric@ericjohannesson.com *)
(* *)
(* This program is free software: you can redistribute it and/or modify *)
(* it under the terms of the GNU General Public License as published by *)
(* the Free Software Foundation, either version 3 of the License, or *)
(* (at your option) any later version. *)
(* *)
(* This program is distributed in the hope that it will be useful, *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)
(* GNU General Public License for more details. *)
(* *)
(* You should have received a copy of the GNU General Public License *)
(* along with this program. If not, see . *)
(* *)
(* ************************************************************************* *)
%{
open FML_types
%}
%token VAR
%token PREFIX_PRED INFIX_PRED NEG_INFIX_PRED
%token PREFIX_FUNC INFIX_FUNC POSTFIX_FUNC
%token UNOP BINOP1 BINOP2 QUANT
%token LPAR RPAR LBR RBR COMMA
%token EOF
%left BINOP2
%left BINOP1
%left INFIX_FUNC
%nonassoc UNOP QUANT
%nonassoc POSTFIX_FUNC
%start main
%type main
%%
main:
|fml EOF { $1 }
;
fml:
|atomic_fml { $1 }
|unop_fml { $1 }
|quant_fml { $1 }
|binop_fml { $1 }
|par_fml { $1 }
;
par_fml:
|lpar fml rpar { $2 }
|lbr fml rbr { $2 }
;
atomic_fml:
|nullary_pred { PredApp ($1,[]) }
|prefix_pred par_terms { PredApp ($1,$2) }
|term infix_pred term { PredApp ($2,[$1;$3]) }
|term neg_infix_pred term { UnopApp (Unop "¬", PredApp ($2,[$1;$3])) }
;
par_terms:
|lpar terms rpar { $2 }
|lbr terms rbr { $2 }
;
unop_fml:
|unop fml %prec UNOP { UnopApp ($1,$2) }
;
quant_fml:
|quant var fml %prec QUANT { QuantApp ($1,$2,$3) }
;
binop_fml:
|fml binop1 fml %prec BINOP1 { BinopApp ($2,$1,$3) }
|fml binop2 fml %prec BINOP2 { BinopApp ($2,$1,$3) }
;
terms:
|term { $1::[] }
|term comma terms { $1::$3 }
;
term:
|var { Atom $1 }
|nullary_func { FuncApp ($1,[]) }
|prefix_func par_terms { FuncApp ($1,$2) }
|term infix_func term %prec INFIX_FUNC { FuncApp ($2,[$1;$3]) }
|term postfix_func { FuncApp ($2,[$1]) }
|par_term { $1 }
;
par_term:
|lpar term rpar { $2 }
|lbr term rbr { $2 }
;
var:
|VAR { Var $1 }
;
nullary_pred:
|PREFIX_PRED { Pred $1 }
;
prefix_pred:
|PREFIX_PRED { Pred $1 }
;
infix_pred:
|INFIX_PRED { Pred $1 }
;
neg_infix_pred:
|NEG_INFIX_PRED { Pred $1 }
;
nullary_func:
|PREFIX_FUNC { Func $1 }
;
prefix_func:
|PREFIX_FUNC { Func $1 }
;
infix_func:
|INFIX_FUNC { Func $1 }
;
postfix_func:
|POSTFIX_FUNC { Func $1 }
;
binop1:
|BINOP1 { Binop $1 }
;
binop2:
|BINOP2 { Binop $1 }
;
unop:
|UNOP { Unop $1 }
;
quant:
|QUANT { Quant $1 }
;
lpar:
|LPAR { }
;
rpar:
|RPAR { }
;
lbr:
|LBR { }
;
rbr:
|RBR { }
;
comma:
|COMMA { }
;