ONijn is an OCaml module of Nijn. It is intended to be used as a tool to generate Coq termination certification scripts from the output of termination tools.
The public API consists of three modules: Syntax, Coq, and Parser.
Syntax Provides submodules for syntactic constructions. It contains representations for Types, Terms, Polynomials, and rewriting rules.Coq Provides interfacing to generate strings that are valid coq constructions. For more details, check the Coq.Grammar and Coq.Proof_script modules.Parser Provides abstract interfacing for creating parsers of file formats accepted by ONijn.In order to certify terminaion of a rewriting system, one must first represent the certificate (stating the termination property) in a way that onijn understands it.
The rewriting formalism of accepted by onijn is AFS (Algebraic Functional Systems).
answer := YES | NO | MAYBE
sort, fn, var := ['a'-'z' 'A'-'Z'] ['a'-'z' 'A'-'Z' '0'-'9']*
type := sort | type -> type
term := var | fn | term term | /\var.term
rewrite_rule := term => termWhere answer represents the termination status given by a termination tool. In the construct for sort, fn, and var, the regex expression ['a'-'z' 'A'-'Z'] ['a'-'z' 'A'-'Z' '0'-'9']* stating the string format accepted as names for sorts, function symbols, and variables, respectively.
In algebraic functional systems, type declarations and types are not the same. The type construct defines the usual simple types. Expressions in type are parsed assuming that => is right-associative, as usual.
We can already represent signature and rewriting systems. Let us take the map TRS as exemple.
map F nil => nil
map F (hd :: tl) => F(hd) :: (map F tl)In onijn format this system is represented as:
Signature: [
cons : a -> list -> list ;
map : list -> (a -> a) -> list ;
nil : list
]
Rules: [
map nil F => nil ;
map (cons X Y) G => cons (G X) (map Y G)
]We represent polynomials with the grammar below:
var := ['a'-'z' 'A'-'Z'] ['a'-'z' 'A'-'Z' '0'-'9']*
poly := n | var | var(poly) | poly + poly | poly * poly
poly_fun := Lam[var_1; ...; var_n] . poly
poly_int := J(fn) = poly_funContinuing with the map example, we represet an interpretation for it in onijn as follows:
Interpretation: [
J(cons) = Lam[y0;y1].3 + 2*y1;
J(map) = Lam[y0;G1].3*y0 + 3*y0*G1(y0);
J(nil) = 3
]An onijn file must end with a list of rules that can be oriented with the given interpretation.
Removed: [
map nil F => nil ;
map (cons X Y) G => cons (G X) (map Y G)
]Putting everything together we get a file map_trs.onijn as follows:
(** This is a comment. It will be ignored by onijn. **)
YES
Signature: [
cons : a -> list -> list ;
map : list -> (a -> a) -> list ;
nil : list
]
Rules: [
map nil F => nil ;
map (cons X Y) G => cons (G X) (map Y G)
]
Interpretation: [
J(cons) = Lam[y0;y1].3 + 2*y1 ;
J(map) = Lam[y0;G1].3*y0 + 3*y0*G1(y0) ;
J(nil) = 3
]
Removed: [
map nil F => nil ;
map (cons X Y) G => cons (G X) (map Y G)
]