author | sultana |
Wed, 19 Feb 2014 15:57:02 +0000 | |
changeset 55591 | 5a9ef4473133 |
parent 55590 | 14e8e51c7fa8 |
child 55592 | 37c1abaf4876 |
permissions | -rw-r--r-- |
47412 | 1 |
(* Title: HOL/TPTP/TPTP_Parser/tptp_to_dot.ML |
2 |
Author: Nik Sultana, Cambridge University Computer Laboratory |
|
3 |
||
4 |
Translates parsed TPTP proofs into DOT format. This can then be processed |
|
5 |
by an accompanying script to translate the proofs into other formats. |
|
55586 | 6 |
|
7 |
It tries to adhere to the symbols used in IDV, as described in |
|
8 |
"An Interactive Derivation Viewer" by Trac & Puzis & Sutcliffe, UITP 2006. |
|
47412 | 9 |
*) |
10 |
||
11 |
signature TPTP_TO_DOT = |
|
12 |
sig |
|
13 |
(*DOT-drawing function, works directly on parsed TPTP*) |
|
14 |
val tptp_dot_node : bool -> bool -> TPTP_Syntax.tptp_line -> string |
|
15 |
||
16 |
(*Parse a (LEO-II+E) proof and produce a DOT file*) |
|
17 |
val write_proof_dot : string -> string -> unit |
|
18 |
end |
|
19 |
||
20 |
structure TPTP_To_Dot : TPTP_TO_DOT = |
|
21 |
struct |
|
22 |
||
23 |
open TPTP_Syntax |
|
24 |
||
25 |
(*Draw an arc between two nodes*) |
|
26 |
fun dot_arc reverse (src, label) target = |
|
27 |
"\"" ^ (if reverse then target else src) ^ |
|
28 |
"\" -> \"" ^ (if reverse then src else target) ^ |
|
29 |
"\" " ^ (case label of |
|
30 |
NONE => "" |
|
31 |
| SOME label => "[label=\"" ^ label ^ "\"];") ^ "\n" |
|
32 |
||
33 |
(*Node shapes indicate the role of the related clauses.*) |
|
34 |
exception NO_ROLE_SHAPE |
|
35 |
fun the_role_shape role = |
|
36 |
case role of |
|
37 |
Role_Axiom => "triangle" |
|
55586 | 38 |
| Role_Hypothesis => "invtrapezium" |
39 |
| Role_Definition => "invtriangle" (*NOTE this is not standard wrt IDV*) |
|
40 |
| Role_Assumption => "trapezium" (*NOTE this is not standard wrt IDV*) |
|
41 |
| Role_Lemma => "hexagon" |
|
42 |
| Role_Theorem => "star" (*NOTE this is not standard wrt IDV*) |
|
55590 | 43 |
|
55591 | 44 |
(*FIXME add a parameter to switch the behaviour described below.*) |
45 |
(*NOTE can change the next three to plaintext to avoid clutter if |
|
46 |
the inference's conclusion formula is also being displayed.*) |
|
47 |
| Role_Conjecture => (* "plaintext" *) "house" |
|
48 |
| Role_Negated_Conjecture => (* "plaintext" *) "invhouse" |
|
55587
5d3db2c626e3
experimenting with improving DOT output, and embedding LaTeX code for formulas (rather than only giving the clause number);
sultana
parents:
55586
diff
changeset
|
49 |
| Role_Plain => "plaintext" (* "circle" *) (*could also use none*) |
55590 | 50 |
|
47412 | 51 |
| Role_Fi_Domain => raise NO_ROLE_SHAPE |
52 |
| Role_Fi_Functors => raise NO_ROLE_SHAPE |
|
53 |
| Role_Fi_Predicates => raise NO_ROLE_SHAPE |
|
54 |
| Role_Type => raise NO_ROLE_SHAPE |
|
55 |
| Role_Unknown => raise NO_ROLE_SHAPE |
|
56 |
||
57 |
fun have_role_shape role = |
|
58 |
(the_role_shape role; true) |
|
59 |
handle NO_ROLE_SHAPE => false |
|
60 |
| exc => raise exc |
|
61 |
||
62 |
(*Different styles are applied to nodes relating to clauses written in |
|
63 |
difference languages.*) |
|
64 |
exception NO_LANG_STYLE |
|
65 |
fun the_lang_style lang = |
|
66 |
case lang of |
|
67 |
CNF => "dotted" |
|
68 |
| FOF => "dashed" |
|
55587
5d3db2c626e3
experimenting with improving DOT output, and embedding LaTeX code for formulas (rather than only giving the clause number);
sultana
parents:
55586
diff
changeset
|
69 |
| THF => "" (* "filled" *) |
47412 | 70 |
| _ => raise NO_LANG_STYLE |
71 |
||
72 |
(*Does the formula just consist of "$false"?*) |
|
73 |
fun is_last_line CNF (Pred (Interpreted_Logic False, [])) = true |
|
74 |
| is_last_line THF (Atom (THF_Atom_term |
|
75 |
(Term_Func (Interpreted_Logic False, [])))) = true |
|
76 |
| is_last_line _ _ = false |
|
77 |
||
78 |
fun tptp_dot_node with_label reverse_arrows |
|
79 |
(Annotated_Formula (_, lang, n, role, fmla_tptp, annot)) = |
|
80 |
(*don't expect to find 'Include' in proofs*) |
|
55587
5d3db2c626e3
experimenting with improving DOT output, and embedding LaTeX code for formulas (rather than only giving the clause number);
sultana
parents:
55586
diff
changeset
|
81 |
if have_role_shape role andalso role <> Role_Definition then |
47412 | 82 |
"\"" ^ n ^ |
83 |
"\" [shape=\"" ^ |
|
84 |
(if is_last_line lang fmla_tptp then "doublecircle" |
|
85 |
else the_role_shape role) ^ |
|
86 |
"\", style=\"" ^ the_lang_style lang ^ |
|
55587
5d3db2c626e3
experimenting with improving DOT output, and embedding LaTeX code for formulas (rather than only giving the clause number);
sultana
parents:
55586
diff
changeset
|
87 |
(if role = Role_Definition then "\"];\n" else |
55591 | 88 |
(* "\", label=\"$" ^ TPTP_Syntax.latex_of_tptp_formula fmla_tptp ^ "$\"];\n") ^ *) |
89 |
(*FIXME add a parameter to switch to using the following code, which lowers, centers, and horizontally-bounds the label. |
|
90 |
(this is useful if you want to keep the shapes but also show formulas)*) |
|
91 |
"\", label=\"\\\\begin{minipage}{10cm}\\\\vspace{21mm}\\\\centering$" ^ TPTP_Syntax.latex_of_tptp_formula fmla_tptp ^ "$\\\\end{minipage}\"];\n") ^ |
|
53389 | 92 |
(case TPTP_Proof.extract_source_info annot of |
93 |
SOME (TPTP_Proof.Inference (rule, _, pinfos)) => |
|
94 |
let |
|
95 |
fun parent_id (TPTP_Proof.Parent n) = n |
|
96 |
| parent_id (TPTP_Proof.ParentWithDetails (n, _)) = n |
|
97 |
val parent_ids = map parent_id pinfos |
|
98 |
in |
|
99 |
map |
|
100 |
(dot_arc reverse_arrows |
|
101 |
(n, if with_label then SOME rule else NONE)) |
|
102 |
parent_ids |
|
103 |
|> implode |
|
104 |
end |
|
105 |
| _ => "") |
|
47412 | 106 |
else "" |
107 |
||
108 |
(*FIXME add opts to label arcs etc*) |
|
109 |
fun write_proof_dot input_file output_file = |
|
110 |
let |
|
111 |
(*rankdir=\"LR\";\n*) |
|
112 |
val defaults = |
|
55587
5d3db2c626e3
experimenting with improving DOT output, and embedding LaTeX code for formulas (rather than only giving the clause number);
sultana
parents:
55586
diff
changeset
|
113 |
"graph[nodesep=3];\n" ^ |
47412 | 114 |
"node[fixedsize=true];\n" ^ |
55587
5d3db2c626e3
experimenting with improving DOT output, and embedding LaTeX code for formulas (rather than only giving the clause number);
sultana
parents:
55586
diff
changeset
|
115 |
"node[width=0.5];\n" ^ |
47412 | 116 |
"node[shape=plaintext];\n" ^ |
55587
5d3db2c626e3
experimenting with improving DOT output, and embedding LaTeX code for formulas (rather than only giving the clause number);
sultana
parents:
55586
diff
changeset
|
117 |
(* "node[fillcolor=lightgray];\n" ^ *) |
55590 | 118 |
"node[fontsize=50];\n" |
47412 | 119 |
in |
120 |
TPTP_Parser.parse_file input_file |
|
55587
5d3db2c626e3
experimenting with improving DOT output, and embedding LaTeX code for formulas (rather than only giving the clause number);
sultana
parents:
55586
diff
changeset
|
121 |
|> map (tptp_dot_node true true) |
47426 | 122 |
|> implode |
47412 | 123 |
|> (fn str => "digraph ProofGraph {\n" ^ defaults ^ str ^ "}") |
124 |
|> File.write (Path.explode output_file) |
|
125 |
end |
|
126 |
||
127 |
end |