src/Pure/Tools/dump.scala
changeset 70859 6e6254bbce1f
parent 70858 f76126e6a1ab
child 70860 f5d0aebfd89c
equal deleted inserted replaced
70858:f76126e6a1ab 70859:6e6254bbce1f
   121     val dirs: List[Path],
   121     val dirs: List[Path],
   122     val select_dirs: List[Path],
   122     val select_dirs: List[Path],
   123     val session_options: Options,
   123     val session_options: Options,
   124     val deps: Sessions.Deps)
   124     val deps: Sessions.Deps)
   125   {
   125   {
       
   126     context =>
       
   127 
   126     def session_dirs: List[Path] = dirs ::: select_dirs
   128     def session_dirs: List[Path] = dirs ::: select_dirs
   127 
   129 
   128     def build_logic(logic: String)
   130     def build_logic(logic: String)
   129     {
   131     {
   130       Build.build_logic(options, logic, build_heap = true, progress = progress,
   132       Build.build_logic(options, logic, build_heap = true, progress = progress,
   132     }
   134     }
   133 
   135 
   134     def session(logic: String, log: Logger = No_Logger): Session =
   136     def session(logic: String, log: Logger = No_Logger): Session =
   135     {
   137     {
   136       build_logic(logic)
   138       build_logic(logic)
   137       new Session(this, logic, log)
   139       new Session(context, logic, log, deps.sessions_structure.imports_topological_order)
   138     }
   140     }
   139   }
   141 
   140 
   142     def partition_sessions(
   141   class Session private[Dump](context: Context, logic: String, log: Logger)
   143       logic: String = default_logic,
       
   144       log: Logger = No_Logger,
       
   145       split_partitions: Boolean = false): List[Session] =
       
   146     {
       
   147       val session_graph = deps.sessions_structure.imports_graph
       
   148 
       
   149       val afp_sessions =
       
   150         if (split_partitions) {
       
   151           (for ((name, (info, _)) <- session_graph.iterator if info.is_afp) yield name).toSet
       
   152         }
       
   153         else Set.empty[String]
       
   154 
       
   155       val afp_bulky_sessions =
       
   156         (for (name <- afp_sessions.iterator if deps.sessions_structure(name).is_afp_bulky)
       
   157           yield name).toList
       
   158 
       
   159       val base_sessions = session_graph.all_preds(List(logic)).reverse
       
   160 
       
   161       val base =
       
   162         if (logic == isabelle.Thy_Header.PURE) Nil
       
   163         else List(new Session(context, isabelle.Thy_Header.PURE, log, base_sessions))
       
   164 
       
   165       val main =
       
   166         new Session(context, logic, log,
       
   167           session_graph.topological_order.filterNot(name =>
       
   168             afp_sessions.contains(name) || base_sessions.contains(name)))
       
   169 
       
   170       val afp =
       
   171         if (afp_sessions.isEmpty) Nil
       
   172         else {
       
   173           val (part1, part2) =
       
   174           {
       
   175             val graph = session_graph.restrict(afp_sessions -- afp_bulky_sessions)
       
   176             val force_partition1 = AFP.force_partition1.filter(graph.defined(_))
       
   177             val force_part1 = graph.all_preds(graph.all_succs(force_partition1)).toSet
       
   178             graph.keys.partition(a => force_part1(a) || graph.is_isolated(a))
       
   179           }
       
   180           for (part <- List(part1, part2, afp_bulky_sessions) if part.nonEmpty)
       
   181             yield new Session(context, logic, log, part)
       
   182         }
       
   183 
       
   184       build_logic(logic)
       
   185       base ::: List(main) ::: afp
       
   186     }
       
   187   }
       
   188 
       
   189   class Session private[Dump](
       
   190     context: Context, val logic: String, log: Logger, val selected_sessions: List[String])
   142   {
   191   {
   143     /* resources */
   192     /* resources */
   144 
   193 
   145     private val progress = context.progress
   194     private val progress = context.progress
       
   195 
       
   196     private val selected_session = selected_sessions.toSet
       
   197 
       
   198     private def selected_theory(name: Document.Node.Name): Boolean =
       
   199       selected_session(context.deps.sessions_structure.theory_qualifier(name.theory))
   146 
   200 
   147     val resources: Headless.Resources =
   201     val resources: Headless.Resources =
   148       Headless.Resources.make(context.session_options, logic, progress = progress, log = log,
   202       Headless.Resources.make(context.session_options, logic, progress = progress, log = log,
   149         session_dirs = context.session_dirs,
   203         session_dirs = context.session_dirs,
   150         include_sessions = context.deps.sessions_structure.imports_topological_order)
   204         include_sessions = context.deps.sessions_structure.imports_topological_order)
   151 
   205 
   152     val used_theories: List[Document.Node.Name] =
   206     val used_theories: List[Document.Node.Name] =
   153     {
   207     {
   154       for {
   208       for {
   155         (name, _) <-
   209         (name, _) <-
   156           context.deps.used_theories_condition(context.session_options, progress = progress)
   210           context.deps.used_theories_condition(context.session_options,
       
   211             restrict = selected_session,
       
   212             progress = progress)
   157         if !resources.session_base.loaded_theory(name.theory)
   213         if !resources.session_base.loaded_theory(name.theory)
   158       } yield name
   214       } yield name
   159     }
   215     }
   160 
   216 
   161 
   217 
   181           Consumer_Thread.fork(name = "dump")(
   237           Consumer_Thread.fork(name = "dump")(
   182             consume = (args: (Document.Snapshot, Document_Status.Node_Status)) =>
   238             consume = (args: (Document.Snapshot, Document_Status.Node_Status)) =>
   183               {
   239               {
   184                 val (snapshot, status) = args
   240                 val (snapshot, status) = args
   185                 val name = snapshot.node_name
   241                 val name = snapshot.node_name
   186                 if (status.ok) {
   242                 if (status.ok && selected_theory(name)) {
   187                   try { process_theory(Args(session, snapshot, status)) }
   243                   try { process_theory(Args(session, snapshot, status)) }
   188                   catch {
   244                   catch {
   189                     case exn: Throwable if !Exn.is_interrupt(exn) =>
   245                     case exn: Throwable if !Exn.is_interrupt(exn) =>
   190                     val msg = Exn.message(exn)
   246                       val msg = Exn.message(exn)
   191                     progress.echo("FAILED to process theory " + name)
   247                       progress.echo("FAILED to process theory " + name)
   192                     progress.echo_error_message(msg)
   248                       progress.echo_error_message(msg)
   193                     consumer_bad_theories.change(Bad_Theory(name, status, List(msg)) :: _)
   249                       consumer_bad_theories.change(Bad_Theory(name, status, List(msg)) :: _)
   194                   }
   250                   }
   195                 }
   251                 }
   196                 else {
   252                 else {
   197                   val msgs =
   253                   val msgs =
   198                     for ((tree, pos) <- snapshot.messages if Protocol.is_error(tree))
   254                     for ((tree, pos) <- snapshot.messages if Protocol.is_error(tree))
   261     progress: Progress = No_Progress,
   317     progress: Progress = No_Progress,
   262     log: Logger = No_Logger,
   318     log: Logger = No_Logger,
   263     dirs: List[Path] = Nil,
   319     dirs: List[Path] = Nil,
   264     select_dirs: List[Path] = Nil,
   320     select_dirs: List[Path] = Nil,
   265     output_dir: Path = default_output_dir,
   321     output_dir: Path = default_output_dir,
       
   322     split_partitions: Boolean = false,
   266     selection: Sessions.Selection = Sessions.Selection.empty)
   323     selection: Sessions.Selection = Sessions.Selection.empty)
   267   {
   324   {
   268     val context =
   325     val context =
   269       Context(options, aspects = aspects, progress = progress, dirs = dirs,
   326       Context(options, aspects = aspects, progress = progress, dirs = dirs,
   270         select_dirs = select_dirs, selection = selection)
   327         select_dirs = select_dirs, selection = selection)
   271 
   328 
   272     context.session(logic, log = log).process((args: Args) =>
   329     context.partition_sessions(logic = logic, log = log, split_partitions = split_partitions).
   273       {
   330       foreach(_.process((args: Args) =>
   274         progress.echo("Processing theory " + args.print_node + " ...")
   331         {
   275         val aspect_args =
   332           progress.echo("Processing theory " + args.print_node + " ...")
   276           Aspect_Args(context.session_options, context.deps, progress, output_dir,
   333           val aspect_args =
   277             args.snapshot, args.status)
   334             Aspect_Args(context.session_options, context.deps, progress, output_dir,
   278         aspects.foreach(_.operation(aspect_args))
   335               args.snapshot, args.status)
   279       })
   336           aspects.foreach(_.operation(aspect_args))
       
   337         }))
   280   }
   338   }
   281 
   339 
   282 
   340 
   283   /* Isabelle tool wrapper */
   341   /* Isabelle tool wrapper */
   284 
   342 
   287     {
   345     {
   288       var aspects: List[Aspect] = known_aspects
   346       var aspects: List[Aspect] = known_aspects
   289       var base_sessions: List[String] = Nil
   347       var base_sessions: List[String] = Nil
   290       var select_dirs: List[Path] = Nil
   348       var select_dirs: List[Path] = Nil
   291       var output_dir = default_output_dir
   349       var output_dir = default_output_dir
       
   350       var split_partitions = false
   292       var requirements = false
   351       var requirements = false
   293       var exclude_session_groups: List[String] = Nil
   352       var exclude_session_groups: List[String] = Nil
   294       var all_sessions = false
   353       var all_sessions = false
       
   354       var logic = default_logic
   295       var dirs: List[Path] = Nil
   355       var dirs: List[Path] = Nil
   296       var session_groups: List[String] = Nil
   356       var session_groups: List[String] = Nil
   297       var logic = default_logic
       
   298       var options = Options.init()
   357       var options = Options.init()
   299       var verbose = false
   358       var verbose = false
   300       var exclude_sessions: List[String] = Nil
   359       var exclude_sessions: List[String] = Nil
   301 
   360 
   302       val getopts = Getopts("""
   361       val getopts = Getopts("""
   305   Options are:
   364   Options are:
   306     -A NAMES     dump named aspects (default: """ + known_aspects.mkString("\"", ",", "\"") + """)
   365     -A NAMES     dump named aspects (default: """ + known_aspects.mkString("\"", ",", "\"") + """)
   307     -B NAME      include session NAME and all descendants
   366     -B NAME      include session NAME and all descendants
   308     -D DIR       include session directory and select its sessions
   367     -D DIR       include session directory and select its sessions
   309     -O DIR       output directory for dumped files (default: """ + default_output_dir + """)
   368     -O DIR       output directory for dumped files (default: """ + default_output_dir + """)
       
   369     -P           split into standard partitions (AFP, non-AFP, ...)
   310     -R           operate on requirements of selected sessions
   370     -R           operate on requirements of selected sessions
   311     -X NAME      exclude sessions from group NAME and all descendants
   371     -X NAME      exclude sessions from group NAME and all descendants
   312     -a           select all sessions
   372     -a           select all sessions
       
   373     -b NAME      base logic image (default """ + isabelle.quote(default_logic) + """)
   313     -d DIR       include session directory
   374     -d DIR       include session directory
   314     -g NAME      select session group NAME
   375     -g NAME      select session group NAME
   315     -l NAME      logic session name (default """ + quote(logic) + """)
       
   316     -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
   376     -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
   317     -v           verbose
   377     -v           verbose
   318     -x NAME      exclude session NAME and all descendants
   378     -x NAME      exclude session NAME and all descendants
   319 
   379 
   320   Dump cumulative PIDE session database, with the following aspects:
   380   Dump cumulative PIDE session database, with the following aspects:
   322 """ + Library.prefix_lines("    ", show_aspects) + "\n",
   382 """ + Library.prefix_lines("    ", show_aspects) + "\n",
   323       "A:" -> (arg => aspects = Library.distinct(space_explode(',', arg)).map(the_aspect(_))),
   383       "A:" -> (arg => aspects = Library.distinct(space_explode(',', arg)).map(the_aspect(_))),
   324       "B:" -> (arg => base_sessions = base_sessions ::: List(arg)),
   384       "B:" -> (arg => base_sessions = base_sessions ::: List(arg)),
   325       "D:" -> (arg => select_dirs = select_dirs ::: List(Path.explode(arg))),
   385       "D:" -> (arg => select_dirs = select_dirs ::: List(Path.explode(arg))),
   326       "O:" -> (arg => output_dir = Path.explode(arg)),
   386       "O:" -> (arg => output_dir = Path.explode(arg)),
       
   387       "P" -> (_ => split_partitions = true),
   327       "R" -> (_ => requirements = true),
   388       "R" -> (_ => requirements = true),
   328       "X:" -> (arg => exclude_session_groups = exclude_session_groups ::: List(arg)),
   389       "X:" -> (arg => exclude_session_groups = exclude_session_groups ::: List(arg)),
   329       "a" -> (_ => all_sessions = true),
   390       "a" -> (_ => all_sessions = true),
       
   391       "b:" -> (arg => logic = arg),
   330       "d:" -> (arg => dirs = dirs ::: List(Path.explode(arg))),
   392       "d:" -> (arg => dirs = dirs ::: List(Path.explode(arg))),
   331       "g:" -> (arg => session_groups = session_groups ::: List(arg)),
   393       "g:" -> (arg => session_groups = session_groups ::: List(arg)),
   332       "l:" -> (arg => logic = arg),
       
   333       "o:" -> (arg => options = options + arg),
   394       "o:" -> (arg => options = options + arg),
   334       "v" -> (_ => verbose = true),
   395       "v" -> (_ => verbose = true),
   335       "x:" -> (arg => exclude_sessions = exclude_sessions ::: List(arg)))
   396       "x:" -> (arg => exclude_sessions = exclude_sessions ::: List(arg)))
   336 
   397 
   337       val sessions = getopts(args)
   398       val sessions = getopts(args)
   343           aspects = aspects,
   404           aspects = aspects,
   344           progress = progress,
   405           progress = progress,
   345           dirs = dirs,
   406           dirs = dirs,
   346           select_dirs = select_dirs,
   407           select_dirs = select_dirs,
   347           output_dir = output_dir,
   408           output_dir = output_dir,
       
   409           split_partitions = split_partitions,
   348           selection = Sessions.Selection(
   410           selection = Sessions.Selection(
   349             requirements = requirements,
   411             requirements = requirements,
   350             all_sessions = all_sessions,
   412             all_sessions = all_sessions,
   351             base_sessions = base_sessions,
   413             base_sessions = base_sessions,
   352             exclude_session_groups = exclude_session_groups,
   414             exclude_session_groups = exclude_session_groups,