-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[petanque] Initial commit, as an OCaml library
- Loading branch information
Showing
13 changed files
with
322 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
(* Compatiblity and general utils *) | ||
|
||
(* We should at some point remove all of this file in favor of a standard | ||
library that suits our needs *) | ||
module Ocaml_414 : sig | ||
module In_channel : sig | ||
val with_open_bin : string -> (in_channel -> 'a) -> 'a | ||
val input_all : in_channel -> string | ||
end | ||
|
||
module Out_channel : sig | ||
val with_open : ('a -> out_channel) -> 'a -> (out_channel -> 'b) -> 'b | ||
val with_open_bin : string -> (out_channel -> 'a) -> 'a | ||
end | ||
end | ||
|
||
val format_to_file : | ||
file:string -> f:(Format.formatter -> 'a -> unit) -> 'a -> unit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
_Petanque_ (pronounced "petanque") is a | ||
[gymnasium](https://gymnasium.farama.org/)-like environment for the | ||
Coq Proof Assistant. | ||
|
||
_Petanque_ is geared towards use cases where interacting at the | ||
document-level (like Flèche provides) in not enough, usually because | ||
we want to work on purely proof-search level vs the document level | ||
one. | ||
|
||
Petanque follows the methodology developed in SerAPI, thus we specify | ||
an OCaml API (`agent.mli`) which is then exposed via some form of RPC. | ||
|
||
## Authors | ||
|
||
- Guilaume Baudart (Inria) | ||
- Emilio J. Gallego Arias (Inria) | ||
- Laetitia Teodorescu (Inria) | ||
|
||
## Acknowledgments | ||
|
||
- Andrei Kozyrev | ||
- Alex Sánchez-Stern | ||
|
||
## Install instructions | ||
|
||
Please see the regular `coq-lsp` install instructions. In general you | ||
have three options: | ||
|
||
- use a released version from Opam | ||
- use a development version directly from the tree | ||
- install a development version using Opam | ||
|
||
See the contributing guide for instructions on how to perform the last | ||
two. | ||
|
||
## Using `petanque` | ||
|
||
To use `petanque`, you need to some form of shell, or you can just | ||
call the API directly from your OCaml program. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
(************************************************************************) | ||
(* Flèche => RL agent: petanque *) | ||
(* Copyright 2019 MINES ParisTech -- Dual License LGPL 2.1 / GPL3+ *) | ||
(* Copyright 2019-2024 Inria -- Dual License LGPL 2.1 / GPL3+ *) | ||
(* Written by: Emilio J. Gallego Arias & coq-lsp contributors *) | ||
(************************************************************************) | ||
|
||
let pet_debug = false | ||
|
||
module State = struct | ||
type t = Coq.State.t | ||
|
||
let hash = Coq.State.hash | ||
let equal = Coq.State.equal | ||
end | ||
|
||
module Env = struct | ||
type t = Fleche.Doc.Env.t | ||
end | ||
|
||
(** Init errors *) | ||
module Init_error = struct | ||
type t = string | ||
end | ||
|
||
module Run_error = struct | ||
type t = | ||
| Interrupted | ||
| Parsing of string | ||
| Coq of string | ||
| Anomaly of string | ||
end | ||
|
||
module Start_error = struct | ||
type t = | ||
| Run of Run_error.t | ||
| Theorem_not_found of string | ||
end | ||
|
||
let init_coq ~debug = | ||
let load_module = Dynlink.loadfile in | ||
let load_plugin = Coq.Loader.plugin_handler None in | ||
Coq.Init.(coq_init { debug; load_module; load_plugin }) | ||
|
||
let cmdline : Coq.Workspace.CmdLine.t = | ||
{ coqlib = Coq_config.coqlib | ||
; coqcorelib = Filename.concat Coq_config.coqlib "../coq-core" | ||
; ocamlpath = None | ||
; vo_load_path = [] | ||
; ml_include_path = [] | ||
; args = [] | ||
; require_libraries = [] | ||
} | ||
|
||
let io = | ||
let trace hdr ?extra:_ msg = | ||
Format.eprintf "@[[trace] %s | %s @]@\n%!" hdr msg | ||
in | ||
let message ~lvl:_ ~message = | ||
Format.eprintf "@[[message] %s @]@\n%!" message | ||
in | ||
let diagnostics ~uri:_ ~version:_ _diags = () in | ||
let fileProgress ~uri:_ ~version:_ _pinfo = () in | ||
let perfData ~uri:_ ~version:_ _perf = () in | ||
{ Fleche.Io.CallBack.trace; message; diagnostics; fileProgress; perfData } | ||
|
||
let read_raw ~uri = | ||
let file = Lang.LUri.File.to_string_file uri in | ||
Stdlib.In_channel.(with_open_text file input_all) | ||
|
||
let find_thm ~(doc : Fleche.Doc.t) ~thm = | ||
let { Fleche.Doc.toc; _ } = doc in | ||
match CString.Map.find_opt thm toc with | ||
| None -> | ||
let msg = Format.asprintf "@[[find_thm] Theorem not found!@]" in | ||
Error (Start_error.Theorem_not_found msg) | ||
| Some range -> | ||
if pet_debug then Format.eprintf "@[[find_thm] Theorem found!@\n@]%!"; | ||
(* let point = (range.start.line, range.start.character) in *) | ||
let point = (range.end_.line, range.end_.character) in | ||
let approx = Fleche.Info.PrevIfEmpty in | ||
let node = Fleche.Info.LC.node ~doc ~point approx in | ||
let error = | ||
Start_error.Theorem_not_found | ||
(Format.asprintf "@[[find_thm] No node found for point (%d, %d) @]" | ||
(fst point) (snd point)) | ||
in | ||
Base.Result.of_option ~error node |> Result.map Fleche.Doc.Node.state | ||
|
||
let pp_diag fmt { Lang.Diagnostic.message; _ } = | ||
Format.fprintf fmt "%a" Pp.pp_with message | ||
|
||
let print_diags (doc : Fleche.Doc.t) = | ||
let d = Fleche.Doc.diags doc in | ||
Format.(eprintf "@[<v>%a@]" (pp_print_list pp_diag) d) | ||
|
||
let init ~token ~debug ~root = | ||
let init = init_coq ~debug in | ||
Fleche.Io.CallBack.set io; | ||
let dir = Lang.LUri.File.to_string_file root in | ||
let ( let+ ) = Base.Result.( >>| ) in | ||
let+ workspace = Coq.Workspace.guess ~token ~debug ~cmdline ~dir in | ||
let files = Coq.Files.make () in | ||
Fleche.Doc.Env.make ~init ~workspace ~files | ||
|
||
let start ~token ~env ~uri ~thm = | ||
let raw = read_raw ~uri in | ||
(* Format.eprintf "raw: @[%s@]%!" raw; *) | ||
let doc = Fleche.Doc.create ~token ~env ~uri ~version:0 ~raw in | ||
print_diags doc; | ||
let target = Fleche.Doc.Target.End in | ||
let doc = Fleche.Doc.check ~io ~token ~target ~doc () in | ||
find_thm ~doc ~thm | ||
|
||
let parse ~loc tac st = | ||
let str = Gramlib.Stream.of_string tac in | ||
let str = Coq.Parsing.Parsable.make ?loc str in | ||
Coq.Parsing.parse ~st str | ||
|
||
let parse_and_execute_in ~token ~loc tac st = | ||
let open Coq.Protect.E.O in | ||
let* ast = parse ~token ~loc tac st in | ||
match ast with | ||
| Some ast -> Fleche.Memo.Interp.eval ~token (st, ast) | ||
(* On EOF we return the previous state, the command was the empty string or a | ||
comment *) | ||
| None -> Coq.Protect.E.ok st | ||
|
||
let protect_to_result (r : _ Coq.Protect.E.t) : (_, _) Result.t = | ||
match r with | ||
| { r = Interrupted; feedback = _ } -> Error Run_error.Interrupted | ||
| { r = Completed (Error (User (_loc, msg))); feedback = _ } -> | ||
Error (Run_error.Coq (Pp.string_of_ppcmds msg)) | ||
| { r = Completed (Error (Anomaly (_loc, msg))); feedback = _ } -> | ||
Error (Run_error.Anomaly (Pp.string_of_ppcmds msg)) | ||
| { r = Completed (Ok r); feedback = _ } -> Ok r | ||
|
||
let run_tac ~token ~st ~tac : (Coq.State.t, Run_error.t) Result.t = | ||
(* Improve with thm? *) | ||
let loc = None in | ||
Coq.State.in_stateM ~token ~st ~f:(parse_and_execute_in ~token ~loc tac) st | ||
|> protect_to_result | ||
|
||
let goals ~token ~st = | ||
let f goals = | ||
let f = Coq.Goals.map_reified_goal ~f:Pp.string_of_ppcmds in | ||
let g = Pp.string_of_ppcmds in | ||
Option.map (Coq.Goals.map_goals ~f ~g) goals | ||
in | ||
Coq.Protect.E.map ~f (Fleche.Info.Goals.goals ~token ~st) |> protect_to_result | ||
|
||
let contents () = () |
Oops, something went wrong.