src/Pure/ProofGeneral/proof_general_pgip.ML
author wenzelm
Tue, 14 May 2013 16:04:26 +0200
changeset 51984 378ecac28f33
parent 51972 39052352427d
child 51985 f6c04bf0123d
permissions -rw-r--r--
misc tuning and simplification;

(*  Title:      Pure/ProofGeneral/proof_general_pgip.ML
    Author:     David Aspinall and Markus Wenzel

Rudiments of PGIP for ProofGeneral preferences.
*)

signature PROOF_GENERAL_PGIP =
sig
  val add_preference: string -> Preferences.preference -> unit
end

structure ProofGeneralPgip : PROOF_GENERAL_PGIP =
struct

(* output PGIP packets *)

val pgip_id = "dummy";
val pgip_serial = Synchronized.counter ();

fun output_pgip refid refseq content =
  XML.Elem (("pgip",
   [("tag", "Isabelle/Isar"), ("id", pgip_id)] @
    PgipTypes.opt_attr "destid" refid @
    [("class", "pg")] @
    PgipTypes.opt_attr "refid" refid @
    [("refseq", refseq)] @
    [("seq", string_of_int (pgip_serial ()))]), content)
  |> XML.string_of
  |> Output.urgent_message;


(* preferences *)

val preferences = Unsynchronized.ref Preferences.pure_preferences;

fun add_preference cat pref =
  CRITICAL (fn () => Unsynchronized.change preferences (Preferences.add cat pref));

fun set_preference pref value =
  (case AList.lookup (op =) (map (fn p => (#name p, p)) (maps snd (! preferences))) pref of
    SOME {set, ...} => set value
  | NONE => error ("Unknown prover preference: " ^ quote pref));


(* process_pgip *)

local

fun invalid_pgip () = raise PgipTypes.PGIP "Invalid PGIP packet received";

fun haspref ({name, descr, default, pgiptype, ...}: Preferences.preference) =
  XML.Elem (("haspref", [("name", name), ("descr", descr), ("default", default)]),
    [PgipTypes.pgiptype_to_xml pgiptype]);

fun process_element refid refseq (XML.Elem (("askprefs", _), _)) =
      ! preferences |> List.app (fn (category, prefs) =>
          output_pgip refid refseq
            [XML.Elem (("hasprefs", [("prefcategory", category)]), map haspref prefs)])
  | process_element _ _ (XML.Elem (("setpref", attrs), data)) =
      let
        val name =
          (case Properties.get attrs "name" of
            SOME name => name
          | NONE => invalid_pgip ());
        val value = XML.content_of data;
      in set_preference name value end
  | process_element _ _ _ = invalid_pgip ();

fun process_pgip str =
  (case XML.parse str of
    XML.Elem (("pgip", attrs), pgips) =>
      let
        val class = PgipTypes.get_attr "class" attrs;
        val dest = PgipTypes.get_attr_opt "destid" attrs;
        val refid = PgipTypes.get_attr_opt "id" attrs;
        val refseq = PgipTypes.get_attr "seq" attrs;
        val processit =
          (case dest of
            NONE => class = "pa"
          | SOME id => id = pgip_id);
       in if processit then List.app (process_element refid refseq) pgips else () end
  | _ => invalid_pgip ())
  handle PgipTypes.PGIP msg => error (msg ^ "\n" ^ str);

in

val _ =
  Outer_Syntax.improper_command
    (("ProofGeneral.process_pgip", Keyword.control), Position.none) "(internal)"
    (Parse.text >> (fn str => Toplevel.imperative (fn () => process_pgip str)));

end;

end;