src/Pure/proof_general.ML
changeset 16821 ba1f6aba44ed
parent 16816 ccf39b7ca3b7
child 16824 c889f499911c
equal deleted inserted replaced
16820:5c9d597e4cb9 16821:ba1f6aba44ed
   159 end;
   159 end;
   160 
   160 
   161 
   161 
   162 (* assembling PGIP packets *)
   162 (* assembling PGIP packets *)
   163 
   163 
       
   164 val pgip_refid  = ref NONE: string option ref;  
   164 val pgip_refseq = ref NONE: string option ref;
   165 val pgip_refseq = ref NONE: string option ref;
   165 val pgip_refid = ref NONE: string option ref;
   166 
   166 
   167 local
   167 local
   168   val pgip_class  = "pg"
   168   val pgip_class  = "pg";
   169   val pgip_tag = "Isabelle/Isar"
   169   val pgip_origin = "Isabelle/Isar";
   170   val pgip_id = ref ""
   170   val pgip_id =
   171   val pgip_seq = ref 0
   171     getenv "HOSTNAME" ^ "/" ^ getenv "USER" ^ "/" ^ Time.toString (Time.now ());
   172   fun pgip_serial () = inc pgip_seq
   172     (* FIXME da: PPID is empty for me: any way to get process ID? *)
       
   173     (* FIXME mak: consider using Path.pack (Path.base (Path.unpack (getenv "ISABELLE_TMP"))),
       
   174        which includes USER already; note that pgip_id above is determined at compile time! *)
       
   175 
   173 
   176   fun assemble_pgips pgips =
   174   fun assemble_pgips pgips =
   177     XML.element
   175     XML.element
   178       "pgip"
   176       "pgip"
   179       ([("class",  pgip_class),
   177       ([("tag",    pgip_tag),
   180         ("origin", pgip_origin),
   178         ("class",  pgip_class),
   181         ("id",     pgip_id)] @
   179         ("id",     !pgip_id)] @
   182        if_none (Option.map (single o (pair "refseq")) (! pgip_refseq)) [] @
   180        if_none (Option.map (single o (pair "destid")) (! pgip_refid)) [] @
   183        if_none (Option.map (single o (pair "refid")) (! pgip_refid)) [] @
   181        (* destid=refid since Isabelle only communicates back to sender,
   184        [("seq",  string_of_int (Library.serial ()))])
   182           so we may omit refid from attributes.
       
   183        if_none (Option.map (single o (pair "refid"))  (! pgip_refid)) [] @
       
   184        *)
       
   185        if_none (Option.map (single o (pair "refseq")) (! pgip_refseq)) [])
   185       pgips;
   186       pgips;
   186 in
   187 
       
   188 in
       
   189 
       
   190 fun init_pgip_session_id () = 
       
   191     pgip_id := getenv "HOSTNAME" ^ "/" ^ getenv "USER" ^ "/" ^
       
   192                getenv "ISABELLE_PID" ^ "/" ^ Time.toString (Time.now ())
       
   193 						       
       
   194 
       
   195 fun matching_pgip_id id = (id = !pgip_id)
   187 
   196 
   188 fun decorated_output bg en prfx =
   197 fun decorated_output bg en prfx =
   189   writeln_default o enclose bg en o prefix_lines prfx;
   198   writeln_default o enclose bg en o prefix_lines prfx;
   190 
   199 
   191 (* FIXME: see Rev 1.48 [PG CVS] for cleaner version of this which can be used
   200 (* FIXME: see Rev 1.48 [PG CVS] for cleaner version of this which can be used
  1282      (* unofficial command for debugging *)
  1291      (* unofficial command for debugging *)
  1283      | "quitpgip" => raise PGIP_QUIT
  1292      | "quitpgip" => raise PGIP_QUIT
  1284      | _ => raise PGIP ("Unrecognized PGIP element: " ^ elem)))
  1293      | _ => raise PGIP ("Unrecognized PGIP element: " ^ elem)))
  1285 
  1294 
  1286 fun process_pgip_tree xml =
  1295 fun process_pgip_tree xml =
  1287     (pgip_refseq := NONE;
  1296     (pgip_refid := NONE;
  1288      pgip_refid := NONE;
  1297      pgip_refseq := NONE;
  1289      (case xml of
  1298      (case xml of
  1290           XML.Elem ("pgip", attrs, pgips) =>
  1299           XML.Elem ("pgip", attrs, pgips) =>
  1291           (let
  1300           (let
  1292                val class = xmlattr "class" attrs
  1301                val class = xmlattr "class" attrs
  1293                val _ = (pgip_refseq := xmlattro "seq" attrs;
  1302 	       val dest  = xmlattro "destid" attrs
  1294                         pgip_refid :=  xmlattro "id" attrs)
  1303                val _ = (pgip_refid :=  xmlattro "id" attrs;
       
  1304 			pgip_refseq := xmlattro "seq" attrs)
  1295            in
  1305            in
  1296                if (class = "pa") then
  1306 	       (* We respond to broadcast messages to provers, or 
  1297                    List.app process_pgip_element pgips
  1307                   messages intended uniquely for us.  Silently ignore rest. *)
  1298                else
  1308                case dest of
  1299                    raise PGIP "PGIP packet for me should have class=\"pa\""
  1309 		   NONE => if (class = "pa") then
       
  1310 			       (List.app process_pgip_element pgips; true)
       
  1311 			   else false
       
  1312 		 | SOME id => if (matching_pgip_id id) then
       
  1313 				  (List.app process_pgip_element pgips; true)
       
  1314 			      else false
  1300            end)
  1315            end)
  1301         | _ => raise PGIP "Invalid PGIP packet received")
  1316         | _ => raise PGIP "Invalid PGIP packet received")
  1302      handle (PGIP msg) =>
  1317      handle (PGIP msg) =>
  1303             (error (msg ^ "\nPGIP error occured in XML text below:\n" ^
  1318             (error (msg ^ "\nPGIP error occured in XML text below:\n" ^
  1304                     (XML.string_of_tree xml))))
  1319                     (XML.string_of_tree xml))))
  1305 
  1320 
  1306 val process_pgip = process_pgip_tree o XML.tree_of_string;
  1321 val process_pgip = K () o process_pgip_tree o XML.tree_of_string
  1307 
  1322 
  1308 end
  1323 end
  1309 
  1324 
  1310 
  1325 
  1311 (* PGIP loop: process PGIP input only *)
  1326 (* PGIP loop: process PGIP input only *)
  1312 
  1327 
  1313 local
  1328 local
  1314 
  1329 
  1315 exception XML_PARSE
  1330 exception XML_PARSE
  1316 
  1331 
  1317 fun loop src : unit =
  1332 fun loop ready src =
  1318     let
  1333     let
  1319         val _ = issue_pgipe "ready" []
  1334         val _ = if ready then (issue_pgipe "ready" []) else ()
  1320         val pgipo = (Source.get_single src)
  1335         val pgipo = (Source.get_single src)
  1321                         handle e => raise XML_PARSE
  1336                         handle e => raise XML_PARSE
  1322     in
  1337     in
  1323         case pgipo of
  1338         case pgipo of
  1324              NONE  => ()
  1339              NONE  => ()
  1325            | SOME (pgip,src') =>
  1340            | SOME (pgip,src') =>
  1326              ((process_pgip_tree pgip); loop src') handle e => handler (e,SOME src')
  1341 	     let 
       
  1342 		 val ready' = (process_pgip_tree pgip) handle e => (handler (e,SOME src'); true)
       
  1343 	     in 
       
  1344 		 loop ready' src'
       
  1345 	     end 
  1327     end handle e => handler (e,SOME src)  (* i.e. error in ready/XML parse *)
  1346     end handle e => handler (e,SOME src)  (* i.e. error in ready/XML parse *)
  1328 
  1347 
  1329 and handler (e,srco) =
  1348 and handler (e,srco) =
  1330     case (e,srco) of
  1349     case (e,srco) of
  1331         (XML_PARSE,SOME src) =>
  1350         (XML_PARSE,SOME src) =>
  1332         (* (!error_fn "Invalid XML input, aborting"; ()) NB: loop OK for tty, but want exit on EOF *)
  1351         panic "Invalid XML input, aborting" (* NB: loop OK for tty, but want exit on EOF *)
  1333          panic "Invalid XML input, aborting"
       
  1334       | (PGIP_QUIT,_) => ()
  1352       | (PGIP_QUIT,_) => ()
  1335       | (ERROR,SOME src) => loop src (* message already given *)
  1353       | (ERROR,SOME src) => loop true src (* message already given *)
  1336       | (Interrupt,SOME src) => (!error_fn "Interrupt during PGIP processing"; loop src)
  1354       | (Interrupt,SOME src) => (!error_fn "Interrupt during PGIP processing"; loop true src)
  1337       | (Toplevel.UNDEF,SOME src) => (error "No working context defined"; loop src) (* usually *)
  1355       | (Toplevel.UNDEF,SOME src) => (error "No working context defined"; loop true src) (* usually *)
  1338       | (e,SOME src) => (error (Toplevel.exn_message e); loop src)
  1356       | (e,SOME src) => (error (Toplevel.exn_message e); loop true src)
  1339       | (_,NONE) => ()
  1357       | (_,NONE) => ()
  1340 in
  1358 in
  1341   (* NB: simple tty for now; later might read from other tty-style sources (e.g. sockets). *)
  1359   (* NB: simple tty for now; later might read from other tty-style sources (e.g. sockets). *)
  1342 
  1360 
  1343   val xmlP = XML.scan_comment_whspc |-- XML.parse_elem >> single
  1361   val xmlP = XML.scan_comment_whspc |-- XML.parse_elem >> single
  1344 
  1362 
  1345   val tty_src = Source.set_prompt "" (Source.source Symbol.stopper xmlP NONE Source.tty)
  1363   val tty_src = Source.set_prompt "" (Source.source Symbol.stopper xmlP NONE Source.tty)
  1346 
  1364 
  1347   val pgip_toplevel =  loop
  1365   val pgip_toplevel =  loop true
  1348 end
  1366 end
  1349 
  1367 
  1350 
  1368 
  1351 (* additional outer syntax for Isar *)
  1369 (* additional outer syntax for Isar *)
  1352 
  1370 
  1420     setup_present_hook ();
  1438     setup_present_hook ();
  1421     set initialized; ()));
  1439     set initialized; ()));
  1422   sync_thy_loader ();
  1440   sync_thy_loader ();
  1423   print_mode := proof_generalN :: (! print_mode \ proof_generalN);
  1441   print_mode := proof_generalN :: (! print_mode \ proof_generalN);
  1424   if pgip then
  1442   if pgip then
  1425     print_mode := pgmlN :: (pgmlatomsN :: (! print_mode \ pgmlN \ pgmlatomsN))
  1443       (init_pgip_session_id();
       
  1444        print_mode := pgmlN :: (pgmlatomsN :: (! print_mode \ pgmlN \ pgmlatomsN)))
  1426   else
  1445   else
  1427     pgip_emacs_compatibility_flag := true;  (* assume this for PG <3.6 compatibility *)
  1446     pgip_emacs_compatibility_flag := true;  (* assume this for PG <3.6 compatibility *)
  1428   set quick_and_dirty;
  1447   set quick_and_dirty;
  1429   ThmDeps.enable ();
  1448   ThmDeps.enable ();
  1430   set_prompts isar pgip;
  1449   set_prompts isar pgip;