Library
Module
Module type
Parameter
Class
Class type
Process an evaluated AST given by Eval.eval
to produce a CNF AST and output DIMACS
ast_to_cnf
is the main function.
Literal: a possibly negated proposition; we denote them as a, b... and their type is homogenous to Prop _
or Not(Prop _)
or Top
or Bottom
. Exples:
a
is a literal, not b
is a literal.Clause: a disjunction (= separated by "or") of possibly negated literals. Example of clause:
a or not b or c or d
is a clauseConjunction: literals separated by "and"; example:
a and b and not and not d
is a conjunctionAST: abstract syntax tree; it is homogenous to Types.Ast.t
and is a recursive tree representing a formula, using Or, And, Implies... Example: the formula (1) has the abstract syntax tree (2):
(a or b) and not c
(1) natural language And (Or (Prop x, Prop x),Not (Prop x))
(2) abstract syntax treeCNF: a Conjunctive Normal Form is an AST that has a special structure with is a conjunction of disjunctions of literals. For example:
(a or not b) and (not c and d)
is a CNF form (a and b) or not (c or d)
is not a CNF formval ast_to_cnf : ?debug_cnf:bool -> Types.Ast.t -> Types.Ast.t
ast_to_cnf
translates the syntaxic tree made of Or, And, Implies, Equiv... Or, And and Not; moreover, it can only be in a conjunction of formulas (see a reminder of their definition above). For example (instead of And, Or we use "and" and "or" and "not"):
(a or not b or c) and (not a or b or d) and (d)
The matching abstract syntax tree (ast) is
And (Or a,(Cor (Not b),c)), (And (Or (Or (Not a),b),d), d)
val clauses_of_cnf :
('a -> 'a) ->
(unit -> 'a) ->
Types.Ast.t ->
'a list list * ('a, string) Stdlib.Hashtbl.t * (string, 'a) Stdlib.Hashtbl.t
clauses_of_cnf
translates the cnf ast (Not, And, Or, Prop; no Bot/Top) into a CNF formula that takes the form of a list of lists of litterals (conjunctions of disjunctions of possibly negated proprositions). neg lit
returns the negation of the litteral (not) fresh ()
returns a newly generated litteral Returns:
The following functions are for displaying dimacs/qdimacs format. Example for the formula
rain=>wet and rain and not wet
we get the dimacs file:
c wet 1 <-- (optionnal) [print_table] c rain 2 c CNF format file <-- by hand p cnf 2 3 <-- by hand (nb_lits, nb_clauses) -2 1 0 <-- [print_clauses] -2 2 0 -2 -1 0
val print_table :
('a -> int) ->
Stdlib.out_channel ->
?prefix:string ->
('a, string) Stdlib.Hashtbl.t ->
unit
print_table
prints the correspondance table between literals (= numbers) and user-defined proposition names, e.g.,
p(1,2) 98
where 98 is the literal id number (given automatically) and p(1,2) is the name of this proposition.
NOTE: you can add a prefix to 'p(1,2) 98', e.g.
string_of_table ~prefix:"c " table
in order to have all lines beginning by 'c' (= comment) in order to comply to the DIMACS format.
print_clauses
prints one disjunction per line ended by 0:
-2 1 0 -2 2 0
IMPORTANT: prints ONLY the clauses. You must print the dimacs/qdimacs header yourself, e.g.:
p cnf <nb_lits> <nb_clauses> with <nb_lits> = Hashtbl.length table <nb_clauses> = List.length clauses