Skip to content

Commit 4599f12

Browse files
authored
Merge pull request #210 from coq-community/revert-209-fix_examples
Revert "Re-implement PixMap writer in Elpi"
2 parents 60902f8 + f3d23e0 commit 4599f12

File tree

14 files changed

+194
-207
lines changed

14 files changed

+194
-207
lines changed

configure.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
cp -f Make.in Make
66

7-
DIRECTORIES="algebra complex coq_reals fta ftc liouville logic metrics model raster reals tactics transc order metric2 stdlib_omissions util classes ode write_image"
7+
DIRECTORIES="algebra complex coq_reals fta ftc liouville logic metrics model raster reals tactics transc order metric2 stdlib_omissions util classes ode"
88

99
find $DIRECTORIES -name "*.v" >>Make
1010

coq-corn.opam

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ install: [make "install"]
4848
depends: [
4949
"coq" {(>= "8.18" & < "8.20~") | (= "dev")}
5050
"coq-math-classes" {(>= "8.8.1") | (= "dev")}
51-
"coq-elpi" {(>= "1.18.0") | (= "dev")}
5251
"coq-bignums"
5352
]
5453

dump/INSTALL

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Dump is a Coq plugin that exports rasters to graymap PGM files.
2+
Rasters are defined in module CoRN.raster.Raster, as matrices of booleans.
3+
4+
Type make to build this plugin, then
5+
Require Import CoRN.dump.theories.Loader
6+
from a Coq file where you have rasters to export.
7+
The vernac command defined by the plugin is DumpGrayMap, which takes
8+
as argument the name of a global definition of a raster. It exports
9+
the raster in file plot.pgm, which it will place in the current directory.
10+
See module CoRN.examples.Circle.

dump/Makefile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
ifeq "$(COQBIN)" ""
2+
COQBIN=$(dir $(shell which coqtop))/
3+
endif
4+
5+
%: Makefile.coq
6+
7+
Makefile.coq: _CoqProject
8+
$(COQBIN)coq_makefile -f _CoqProject -o Makefile.coq
9+
10+
tests: all
11+
@$(MAKE) -C tests -s clean
12+
@$(MAKE) -C tests -s all
13+
14+
-include Makefile.coq

dump/_CoqProject

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-R theories CoRN.dump.theories
2+
-I src
3+
4+
theories/Loader.v
5+
6+
src/g_dump.mlg
7+
src/dump_plugin.mlpack

dump/src/dump_plugin.mlpack

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
G_dump

dump/src/dune

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(library
2+
(name dump_plugin)
3+
(public_name coq.plugins.tutorial.p0)
4+
(libraries coq.plugins.ltac))
5+
6+
(coq.pp (modules g_dump))

dump/src/g_dump.mlg

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
DECLARE PLUGIN "dump_plugin"
2+
3+
{
4+
5+
open Pp
6+
open Names
7+
open Printer
8+
open Globnames
9+
open Stdarg
10+
open Typeops
11+
open Constr
12+
13+
exception Bad_list
14+
exception Bad_int
15+
16+
let rec int_of_pos (p : Constr.t) : int =
17+
if isApp p then
18+
(let (constructorTag, args) = destApp p in
19+
let (r,_) = destRef constructorTag in
20+
match r with
21+
| GlobRef.ConstructRef (_,r) -> (* r is the number of the constructor,
22+
starting from 1. *)
23+
(if r = 1 then 2*int_of_pos args.(0)+1 else 2*int_of_pos args.(0))
24+
| _ -> raise Bad_int)
25+
else 1
26+
27+
let int_of_z (z : Constr.t) : int =
28+
if isApp z then
29+
(let (constructorTag, args) = destApp z in
30+
let (r,_) = destRef constructorTag in
31+
match r with
32+
| GlobRef.ConstructRef (_,r) -> (* r is the number of the constructor,
33+
starting from 1. *)
34+
(if r = 2 then int_of_pos args.(0) else -int_of_pos args.(0))
35+
| _ -> raise Bad_int)
36+
else 0
37+
38+
let pair_int_of_pair_z (zz : Constr.t) : int*int =
39+
if isApp zz then
40+
(let (constructorTag, args) = destApp zz in
41+
(int_of_z args.(2), int_of_z args.(3)))
42+
else raise Bad_int
43+
44+
let rec process_constr_list (l : Constr.t) (f : Constr.t -> unit) : unit =
45+
if isApp l then
46+
(let (constructorTag, args) = destApp l in
47+
if Array.length args = 3 then
48+
(* args stores type, current element and tail *)
49+
(f args.(1) ; process_constr_list args.(2) f)
50+
else ()) (* empty list *)
51+
else raise Bad_list
52+
53+
let dump_bool_list (l : Constr.t) (oc : out_channel) : unit =
54+
process_constr_list l
55+
(fun b ->
56+
(* b is either true of false, which are constructors of the type bool *)
57+
let (r,_) = destRef b in
58+
match r with
59+
| GlobRef.ConstructRef (_,r) -> (* r is the number of the constructor,
60+
starting from 1. *)
61+
output_string oc (if r = 1 then "1 " else "0 ")
62+
| _ -> raise Bad_list) ;
63+
output_string oc "\n"
64+
65+
let dump_pgm (raster : Constr.t) (rastertype : Pp.t) =
66+
let bufType = Buffer.create 1000 in
67+
let fmtType = Format.formatter_of_buffer bufType in
68+
pp_with fmtType rastertype;
69+
Format.pp_print_flush fmtType ();
70+
let (strType : string) = Buffer.contents bufType in
71+
if Str.string_match (Str.regexp "(sparse_raster \\([0-9]+\\) \\([0-9]+\\))")
72+
strType 0 then
73+
(let line_count = int_of_string (Str.matched_group 2 strType) in
74+
let column_count = int_of_string (Str.matched_group 1 strType) in
75+
let oc = open_out "plot.pgm" in
76+
let pixels = Array.make_matrix line_count column_count false in
77+
let (constructorTag, args) = destApp raster in
78+
process_constr_list args.(2)
79+
(fun zz -> let (i,j) = pair_int_of_pair_z zz in
80+
pixels.(i).(j) <- true);
81+
(* P2 is the magic number for PGM ascii files.
82+
Then come the dimensions of the image and
83+
the number of levels of gray, ie 1. *)
84+
output_string oc "P2\n";
85+
output_string oc (string_of_int column_count);
86+
output_string oc " ";
87+
output_string oc (string_of_int line_count);
88+
output_string oc "\n1\n";
89+
(for i=0 to line_count-1 do
90+
for j=0 to column_count-1 do
91+
output_string oc (if pixels.(i).(j) then "1 " else "0 ")
92+
done;
93+
output_string oc "\n"
94+
done);
95+
close_out oc)
96+
else failwith "Bad raster"
97+
98+
(* Write the global term t to an ascii PGM file (portable gray map),
99+
which is a format for grayscale matrices.
100+
t should be already reduced, for example by
101+
Definition t := Eval vm_compute in [some raster expression] *)
102+
let eval_and_dump_pgm (t : Libnames.qualid) =
103+
let env = Global.env () in
104+
prerr_endline "dumping to plot.pgm";
105+
let (tg : GlobRef.t) = Constrintern.intern_reference t in
106+
let (tt : Constr.types) = fst (type_of_global_in_context env tg) in
107+
let (c : Constr.constr) = printable_constr_of_global tg in
108+
(* Delta-reduce c to unfold the name of the matrix of booleans
109+
and get its contents. *)
110+
let evalc = Reductionops.whd_delta env (Evd.from_env env) (EConstr.of_constr c) in
111+
let evalt = Reductionops.nf_all env (Evd.from_env env) (EConstr.of_constr tt) in
112+
dump_pgm (EConstr.to_constr (Evd.from_env env) evalc)
113+
(pr_econstr_env env (Evd.from_env env) evalt)
114+
115+
}
116+
117+
VERNAC COMMAND EXTEND DumpGrayMap CLASSIFIED AS QUERY
118+
| [ "DumpGrayMap" global(a) ] -> { eval_and_dump_pgm a }
119+
END
120+

dump/theories/Loader.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Declare ML Module "dump_plugin".

examples/Circle.v

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
(* I define the image of a path, a [Compact] subset of the plane.*)
44
(* Finally, plot a hi-res Circle*)
55

6-
From CoRN Require Import Plot RasterQ Qmetric.
6+
Require Import Plot RasterQ Qmetric.
77
Require Import CoRN.reals.fast.Interval.
88
Require Import CoRN.metric2.MetricMorphisms.
99
Require Import CoRN.reals.faster.ARArith.
10-
From CoRN Require Import ARplot.
10+
Require Import ARplot.
1111
Require Import CoRN.reals.faster.ARcos
1212
CoRN.reals.faster.ARsin
1313
CoRN.reals.faster.ARexp
1414
CoRN.reals.faster.ARbigD
1515
CoRN.reals.faster.ARinterval.
1616
Require Import CoRN.reals.fast.CRtrans.
17-
Require Import CoRN.write_image.WritePPM.
17+
Require Import CoRN.dump.theories.Loader.
1818

1919
Local Open Scope uc_scope.
2020

@@ -47,19 +47,21 @@ Definition Cos_faster : sparse_raster _ _
4747

4848
End PlotCirclePath.
4949

50-
Definition Circle_bigD : sparse_raster _ _
51-
:= @Circle_faster bigD _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ bigD_appRat.
50+
(* 6 seconds *)
51+
Time Definition Circle_bigD : sparse_raster _ _
52+
:= Eval vm_compute in
53+
@Circle_faster bigD _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ bigD_appRat.
5254

53-
(* 3.7s on Apple M1 - this is mostly the creation of the sparse raster *)
54-
Time Elpi WritePPM "Circle.ppm" ( Circle_bigD ).
55-
(* Now have a look at Circle.ppm *)
55+
DumpGrayMap Circle_bigD.
56+
(* Now have a look at plot.pgm *)
5657

57-
Definition Cos_bigD : sparse_raster _ _
58-
:= @Cos_faster bigD _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ bigD_appRat.
58+
Time Definition Cos_bigD : sparse_raster _ _
59+
:= Eval vm_compute in
60+
@Cos_faster bigD _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ bigD_appRat.
61+
62+
DumpGrayMap Cos_bigD.
63+
(* Now have a look at plot.pgm *)
5964

60-
(* 3.1s on Apple M1 *)
61-
Time Elpi WritePPM "Cos.ppm" ( Cos_bigD ).
62-
(* Now have a look at Cos.ppm *)
6365

6466
Definition CircleFunction_aux
6567
: ProductMS Q_as_MetricSpace Q_as_MetricSpace --> ProductMS CR CR
@@ -68,18 +70,20 @@ Definition CircleFunction_aux
6870
Definition CirclePath : Q_as_MetricSpace --> Complete Q2:=
6971
(uc_compose (uc_compose Couple CircleFunction_aux) (diag Q_as_MetricSpace)).
7072
(* The following hangs:
71-
TODO this does not even compile
7273
Definition CirclePath': UCFunction Q R2:=
73-
ucFunction (fun q:Q => Couple (cos_uc q, sin_uc q)). *)
74+
ucFunction (fun q:Q => Couple (cos_uc q, sin_uc q)).*)
7475

7576

76-
Definition Circle : sparse_raster _ _
77-
:= (let (_,r) := Plot.PlotPath 0 7 (-(1)) 1 (reflexivity _)
77+
(* 20 seconds *)
78+
(* The raster must be evaluated before being plotted by DumpGrayMap,
79+
here with vm_compute. *)
80+
Time Definition Circle : sparse_raster _ _
81+
:= Eval vm_compute in
82+
(let (_,r) := Plot.PlotPath 0 7 (-(1)) 1 (reflexivity _)
7883
(-(1)) 1 (reflexivity _) 200 CirclePath
7984
in r).
8085

81-
(* 16.3 seconds on Apple M1 *)
82-
Time Elpi WritePPM "Circle2.ppm" ( Circle ).
83-
(* Now have a look at Circle2.ppm *)
86+
DumpGrayMap Circle.
87+
(* Now have a look at plot.pgm *)
8488

8589

0 commit comments

Comments
 (0)