diff --git a/lib/texinputs/isabellesym.sty b/lib/texinputs/isabellesym.sty --- a/lib/texinputs/isabellesym.sty +++ b/lib/texinputs/isabellesym.sty @@ -1,496 +1,497 @@ %% %% definitions of standard Isabelle symbols %% \newcommand{\isasymzero}{\isamath{\mathbf{0}}} %requires amssymb \newcommand{\isasymone}{\isamath{\mathbf{1}}} %requires amssymb \newcommand{\isasymtwo}{\isamath{\mathbf{2}}} %requires amssymb \newcommand{\isasymthree}{\isamath{\mathbf{3}}} %requires amssymb \newcommand{\isasymfour}{\isamath{\mathbf{4}}} %requires amssymb \newcommand{\isasymfive}{\isamath{\mathbf{5}}} %requires amssymb \newcommand{\isasymsix}{\isamath{\mathbf{6}}} %requires amssymb \newcommand{\isasymseven}{\isamath{\mathbf{7}}} %requires amssymb \newcommand{\isasymeight}{\isamath{\mathbf{8}}} %requires amssymb \newcommand{\isasymnine}{\isamath{\mathbf{9}}} %requires amssymb \newcommand{\isasymA}{\isamath{\mathcal{A}}} \newcommand{\isasymB}{\isamath{\mathcal{B}}} \newcommand{\isasymC}{\isamath{\mathcal{C}}} \newcommand{\isasymD}{\isamath{\mathcal{D}}} \newcommand{\isasymE}{\isamath{\mathcal{E}}} \newcommand{\isasymF}{\isamath{\mathcal{F}}} \newcommand{\isasymG}{\isamath{\mathcal{G}}} \newcommand{\isasymH}{\isamath{\mathcal{H}}} \newcommand{\isasymI}{\isamath{\mathcal{I}}} \newcommand{\isasymJ}{\isamath{\mathcal{J}}} \newcommand{\isasymK}{\isamath{\mathcal{K}}} \newcommand{\isasymL}{\isamath{\mathcal{L}}} \newcommand{\isasymM}{\isamath{\mathcal{M}}} \newcommand{\isasymN}{\isamath{\mathcal{N}}} \newcommand{\isasymO}{\isamath{\mathcal{O}}} \newcommand{\isasymP}{\isamath{\mathcal{P}}} \newcommand{\isasymQ}{\isamath{\mathcal{Q}}} \newcommand{\isasymR}{\isamath{\mathcal{R}}} \newcommand{\isasymS}{\isamath{\mathcal{S}}} \newcommand{\isasymT}{\isamath{\mathcal{T}}} \newcommand{\isasymU}{\isamath{\mathcal{U}}} \newcommand{\isasymV}{\isamath{\mathcal{V}}} \newcommand{\isasymW}{\isamath{\mathcal{W}}} \newcommand{\isasymX}{\isamath{\mathcal{X}}} \newcommand{\isasymY}{\isamath{\mathcal{Y}}} \newcommand{\isasymZ}{\isamath{\mathcal{Z}}} \newcommand{\isasyma}{\isamath{\mathrm{a}}} \newcommand{\isasymb}{\isamath{\mathrm{b}}} \newcommand{\isasymc}{\isamath{\mathrm{c}}} \newcommand{\isasymd}{\isamath{\mathrm{d}}} \newcommand{\isasyme}{\isamath{\mathrm{e}}} \newcommand{\isasymf}{\isamath{\mathrm{f}}} \newcommand{\isasymg}{\isamath{\mathrm{g}}} \newcommand{\isasymh}{\isamath{\mathrm{h}}} \newcommand{\isasymi}{\isamath{\mathrm{i}}} \newcommand{\isasymj}{\isamath{\mathrm{j}}} \newcommand{\isasymk}{\isamath{\mathrm{k}}} \newcommand{\isasyml}{\isamath{\mathrm{l}}} \newcommand{\isasymm}{\isamath{\mathrm{m}}} \newcommand{\isasymn}{\isamath{\mathrm{n}}} \newcommand{\isasymo}{\isamath{\mathrm{o}}} \newcommand{\isasymp}{\isamath{\mathrm{p}}} \newcommand{\isasymq}{\isamath{\mathrm{q}}} \newcommand{\isasymr}{\isamath{\mathrm{r}}} \newcommand{\isasyms}{\isamath{\mathrm{s}}} \newcommand{\isasymt}{\isamath{\mathrm{t}}} \newcommand{\isasymu}{\isamath{\mathrm{u}}} \newcommand{\isasymv}{\isamath{\mathrm{v}}} \newcommand{\isasymw}{\isamath{\mathrm{w}}} \newcommand{\isasymx}{\isamath{\mathrm{x}}} \newcommand{\isasymy}{\isamath{\mathrm{y}}} \newcommand{\isasymz}{\isamath{\mathrm{z}}} \newcommand{\isasymAA}{\isamath{\mathfrak{A}}} %requires eufrak \newcommand{\isasymBB}{\isamath{\mathfrak{B}}} %requires eufrak \newcommand{\isasymCC}{\isamath{\mathfrak{C}}} %requires eufrak \newcommand{\isasymDD}{\isamath{\mathfrak{D}}} %requires eufrak \newcommand{\isasymEE}{\isamath{\mathfrak{E}}} %requires eufrak \newcommand{\isasymFF}{\isamath{\mathfrak{F}}} %requires eufrak \newcommand{\isasymGG}{\isamath{\mathfrak{G}}} %requires eufrak \newcommand{\isasymHH}{\isamath{\mathfrak{H}}} %requires eufrak \newcommand{\isasymII}{\isamath{\mathfrak{I}}} %requires eufrak \newcommand{\isasymJJ}{\isamath{\mathfrak{J}}} %requires eufrak \newcommand{\isasymKK}{\isamath{\mathfrak{K}}} %requires eufrak \newcommand{\isasymLL}{\isamath{\mathfrak{L}}} %requires eufrak \newcommand{\isasymMM}{\isamath{\mathfrak{M}}} %requires eufrak \newcommand{\isasymNN}{\isamath{\mathfrak{N}}} %requires eufrak \newcommand{\isasymOO}{\isamath{\mathfrak{O}}} %requires eufrak \newcommand{\isasymPP}{\isamath{\mathfrak{P}}} %requires eufrak \newcommand{\isasymQQ}{\isamath{\mathfrak{Q}}} %requires eufrak \newcommand{\isasymRR}{\isamath{\mathfrak{R}}} %requires eufrak \newcommand{\isasymSS}{\isamath{\mathfrak{S}}} %requires eufrak \newcommand{\isasymTT}{\isamath{\mathfrak{T}}} %requires eufrak \newcommand{\isasymUU}{\isamath{\mathfrak{U}}} %requires eufrak \newcommand{\isasymVV}{\isamath{\mathfrak{V}}} %requires eufrak \newcommand{\isasymWW}{\isamath{\mathfrak{W}}} %requires eufrak \newcommand{\isasymXX}{\isamath{\mathfrak{X}}} %requires eufrak \newcommand{\isasymYY}{\isamath{\mathfrak{Y}}} %requires eufrak \newcommand{\isasymZZ}{\isamath{\mathfrak{Z}}} %requires eufrak \newcommand{\isasymaa}{\isamath{\mathfrak{a}}} %requires eufrak \newcommand{\isasymbb}{\isamath{\mathfrak{b}}} %requires eufrak \newcommand{\isasymcc}{\isamath{\mathfrak{c}}} %requires eufrak \newcommand{\isasymdd}{\isamath{\mathfrak{d}}} %requires eufrak \newcommand{\isasymee}{\isamath{\mathfrak{e}}} %requires eufrak \newcommand{\isasymff}{\isamath{\mathfrak{f}}} %requires eufrak \newcommand{\isasymgg}{\isamath{\mathfrak{g}}} %requires eufrak \newcommand{\isasymhh}{\isamath{\mathfrak{h}}} %requires eufrak \newcommand{\isasymii}{\isamath{\mathfrak{i}}} %requires eufrak \newcommand{\isasymjj}{\isamath{\mathfrak{j}}} %requires eufrak \newcommand{\isasymkk}{\isamath{\mathfrak{k}}} %requires eufrak \newcommand{\isasymll}{\isamath{\mathfrak{l}}} %requires eufrak \newcommand{\isasymmm}{\isamath{\mathfrak{m}}} %requires eufrak \newcommand{\isasymnn}{\isamath{\mathfrak{n}}} %requires eufrak \newcommand{\isasymoo}{\isamath{\mathfrak{o}}} %requires eufrak \newcommand{\isasympp}{\isamath{\mathfrak{p}}} %requires eufrak \newcommand{\isasymqq}{\isamath{\mathfrak{q}}} %requires eufrak \newcommand{\isasymrr}{\isamath{\mathfrak{r}}} %requires eufrak \newcommand{\isasymss}{\isamath{\mathfrak{s}}} %requires eufrak \newcommand{\isasymtt}{\isamath{\mathfrak{t}}} %requires eufrak \newcommand{\isasymuu}{\isamath{\mathfrak{u}}} %requires eufrak \newcommand{\isasymvv}{\isamath{\mathfrak{v}}} %requires eufrak \newcommand{\isasymww}{\isamath{\mathfrak{w}}} %requires eufrak \newcommand{\isasymxx}{\isamath{\mathfrak{x}}} %requires eufrak \newcommand{\isasymyy}{\isamath{\mathfrak{y}}} %requires eufrak \newcommand{\isasymzz}{\isamath{\mathfrak{z}}} %requires eufrak \newcommand{\isasymalpha}{\isamath{\alpha}} \newcommand{\isasymbeta}{\isamath{\beta}} \newcommand{\isasymgamma}{\isamath{\gamma}} \newcommand{\isasymdelta}{\isamath{\delta}} \newcommand{\isasymepsilon}{\isamath{\varepsilon}} \newcommand{\isasymzeta}{\isamath{\zeta}} \newcommand{\isasymeta}{\isamath{\eta}} \newcommand{\isasymtheta}{\isamath{\vartheta}} \newcommand{\isasymiota}{\isamath{\iota}} \newcommand{\isasymkappa}{\isamath{\kappa}} \newcommand{\isasymlambda}{\isamath{\lambda}} \newcommand{\isasymmu}{\isamath{\mu}} \newcommand{\isasymnu}{\isamath{\nu}} \newcommand{\isasymxi}{\isamath{\xi}} \newcommand{\isasympi}{\isamath{\pi}} \newcommand{\isasymrho}{\isamath{\varrho}} \newcommand{\isasymsigma}{\isamath{\sigma}} \newcommand{\isasymtau}{\isamath{\tau}} \newcommand{\isasymupsilon}{\isamath{\upsilon}} \newcommand{\isasymphi}{\isamath{\varphi}} \newcommand{\isasymchi}{\isamath{\chi}} \newcommand{\isasympsi}{\isamath{\psi}} \newcommand{\isasymomega}{\isamath{\omega}} \newcommand{\isasymGamma}{\isamath{\Gamma}} \newcommand{\isasymDelta}{\isamath{\Delta}} \newcommand{\isasymTheta}{\isamath{\Theta}} \newcommand{\isasymLambda}{\isamath{\Lambda}} \newcommand{\isasymXi}{\isamath{\Xi}} \newcommand{\isasymPi}{\isamath{\Pi}} \newcommand{\isasymSigma}{\isamath{\Sigma}} \newcommand{\isasymUpsilon}{\isamath{\Upsilon}} \newcommand{\isasymPhi}{\isamath{\Phi}} \newcommand{\isasymPsi}{\isamath{\Psi}} \newcommand{\isasymOmega}{\isamath{\Omega}} \newcommand{\isasymbbbA}{\isamath{\bbbA}} %requires font txmia from txfonts \newcommand{\isasymbool}{\isamath{\bbbB}} %requires font txmia from txfonts \newcommand{\isasymcomplex}{\isamath{\bbbC}} %requires font txmia from txfonts \newcommand{\isasymbbbD}{\isamath{\bbbD}} %requires font txmia from txfonts \newcommand{\isasymbbbE}{\isamath{\bbbE}} %requires font txmia from txfonts \newcommand{\isasymbbbF}{\isamath{\bbbF}} %requires font txmia from txfonts \newcommand{\isasymbbbG}{\isamath{\bbbG}} %requires font txmia from txfonts \newcommand{\isasymbbbH}{\isamath{\bbbH}} %requires font txmia from txfonts \newcommand{\isasymbbbI}{\isamath{\bbbI}} %requires font txmia from txfonts \newcommand{\isasymbbbJ}{\isamath{\bbbJ}} %requires font txmia from txfonts \newcommand{\isasymbbbK}{\isamath{\bbbK}} %requires font txmia from txfonts \newcommand{\isasymbbbL}{\isamath{\bbbL}} %requires font txmia from txfonts \newcommand{\isasymbbbM}{\isamath{\bbbM}} %requires font txmia from txfonts \newcommand{\isasymnat}{\isamath{\bbbN}} %requires font txmia from txfonts \newcommand{\isasymbbbO}{\isamath{\bbbO}} %requires font txmia from txfonts \newcommand{\isasymbbbP}{\isamath{\bbbP}} %requires font txmia from txfonts \newcommand{\isasymrat}{\isamath{\bbbQ}} %requires font txmia from txfonts \newcommand{\isasymreal}{\isamath{\bbbR}} %requires font txmia from txfonts \newcommand{\isasymbbbS}{\isamath{\bbbS}} %requires font txmia from txfonts \newcommand{\isasymbbbT}{\isamath{\bbbT}} %requires font txmia from txfonts \newcommand{\isasymbbbU}{\isamath{\bbbU}} %requires font txmia from txfonts \newcommand{\isasymbbbV}{\isamath{\bbbV}} %requires font txmia from txfonts \newcommand{\isasymbbbW}{\isamath{\bbbW}} %requires font txmia from txfonts \newcommand{\isasymbbbX}{\isamath{\bbbX}} %requires font txmia from txfonts \newcommand{\isasymbbbY}{\isamath{\bbbY}} %requires font txmia from txfonts \newcommand{\isasymint}{\isamath{\bbbZ}} %requires font txmia from txfonts \newcommand{\isasymleftarrow}{\isamath{\leftarrow}} \newcommand{\isasymrightarrow}{\isamath{\rightarrow}} \newcommand{\isasymlongleftarrow}{\isamath{\longleftarrow}} \newcommand{\isasymlongrightarrow}{\isamath{\longrightarrow}} \newcommand{\isasymlonglongleftarrow}{\isamath{\xleftarrow{\hphantom{AAA}}}} %requires amsmath \newcommand{\isasymlonglongrightarrow}{\isamath{\xrightarrow{\hphantom{AAA}}}} %requires amsmath \newcommand{\isasymlonglonglongleftarrow}{\isamath{\xleftarrow{\hphantom{AAAA}}}} %requires amsmath \newcommand{\isasymlonglonglongrightarrow}{\isamath{\xrightarrow{\hphantom{AAAA}}}} %requires amsmath \newcommand{\isasymLeftarrow}{\isamath{\Leftarrow}} \newcommand{\isasymRightarrow}{\isamath{\Rightarrow}} \newcommand{\isasymLongleftarrow}{\isamath{\Longleftarrow}} \newcommand{\isasymLongrightarrow}{\isamath{\Longrightarrow}} \newcommand{\isasymLleftarrow}{\isamath{\Lleftarrow}} %requires amssymb \newcommand{\isasymRrightarrow}{\isamath{\Rrightarrow}} %requires amssymb \newcommand{\isasymleftrightarrow}{\isamath{\leftrightarrow}} \newcommand{\isasymLeftrightarrow}{\isamath{\Leftrightarrow}} \newcommand{\isasymlongleftrightarrow}{\isamath{\longleftrightarrow}} \newcommand{\isasymLongleftrightarrow}{\isamath{\Longleftrightarrow}} \newcommand{\isasymmapsto}{\isamath{\mapsto}} \newcommand{\isasymlongmapsto}{\isamath{\longmapsto}} \newcommand{\isasymmidarrow}{\isamath{\relbar}} \newcommand{\isasymMidarrow}{\isamath{\Relbar}} \newcommand{\isasymhookleftarrow}{\isamath{\hookleftarrow}} \newcommand{\isasymhookrightarrow}{\isamath{\hookrightarrow}} \newcommand{\isasymleftharpoondown}{\isamath{\leftharpoondown}} \newcommand{\isasymrightharpoondown}{\isamath{\rightharpoondown}} \newcommand{\isasymleftharpoonup}{\isamath{\leftharpoonup}} \newcommand{\isasymrightharpoonup}{\isamath{\rightharpoonup}} \newcommand{\isasymrightleftharpoons}{\isamath{\rightleftharpoons}} \newcommand{\isasymleadsto}{\isamath{\leadsto}} %requires amssymb \newcommand{\isasymdownharpoonleft}{\isamath{\downharpoonleft}} %requires amssymb \newcommand{\isasymdownharpoonright}{\isamath{\downharpoonright}} %requires amssymb \newcommand{\isasymupharpoonleft}{\isamath{\upharpoonleft}} %requires amssymb \newcommand{\isasymupharpoonright}{\isamath{\upharpoonright}} %requires amssymb \newcommand{\isasymrestriction}{\isamath{\restriction}} %requires amssymb \newcommand{\isasymColon}{\isamath{\mathrel{::}}} \newcommand{\isasymup}{\isamath{\uparrow}} \newcommand{\isasymUp}{\isamath{\Uparrow}} \newcommand{\isasymdown}{\isamath{\downarrow}} \newcommand{\isasymDown}{\isamath{\Downarrow}} \newcommand{\isasymupdown}{\isamath{\updownarrow}} \newcommand{\isasymUpdown}{\isamath{\Updownarrow}} \newcommand{\isasymlangle}{\isamath{\langle}} \newcommand{\isasymrangle}{\isamath{\rangle}} \newcommand{\isasymllangle}{\isamath{\langle\mskip-5mu\langle}} \newcommand{\isasymrrangle}{\isamath{\rangle\mskip-5mu\rangle}} \newcommand{\isasymlceil}{\isamath{\lceil}} \newcommand{\isasymrceil}{\isamath{\rceil}} \newcommand{\isasymlfloor}{\isamath{\lfloor}} \newcommand{\isasymrfloor}{\isamath{\rfloor}} \newcommand{\isasymlparr}{\isamath{\mathopen{(\mkern-3.3mu\mid}}} \newcommand{\isasymrparr}{\isamath{\mathclose{\mid\mkern-3.3mu)}}} \newcommand{\isasymlbrakk}{\isamath{\mathopen{\lbrack\mkern-3mu\lbrack}}} \newcommand{\isasymrbrakk}{\isamath{\mathclose{\rbrack\mkern-3mu\rbrack}}} \newcommand{\isasymlbrace}{\isamath{\mathopen{\lbrace\mkern-4.3mu\mid}}} \newcommand{\isasymrbrace}{\isamath{\mathclose{\mid\mkern-4.3mu\rbrace}}} \newcommand{\isasymlblot}{\isamath{{\langle}\mkern -3.5mu{|}}} \newcommand{\isasymrblot}{\isamath{{|}\mkern -3.5mu{\rangle}}} \newcommand{\isasymguillemotleft}{\isatext{\guillemotleft}} \newcommand{\isasymguillemotright}{\isatext{\guillemotright}} \newcommand{\isasymbottom}{\isamath{\bot}} \newcommand{\isasymtop}{\isamath{\top}} \newcommand{\isasymand}{\isamath{\wedge}} \newcommand{\isasymAnd}{\isamath{\bigwedge}} \newcommand{\isasymor}{\isamath{\vee}} \newcommand{\isasymOr}{\isamath{\bigvee}} \newcommand{\isasymforall}{\isamath{\forall\,}} \newcommand{\isasymexists}{\isamath{\exists\,}} \newcommand{\isasymnot}{\isamath{\neg}} \newcommand{\isasymnexists}{\isamath{\nexists\,}} %requires amssymb \newcommand{\isasymcircle}{\isamath{\ocircle}} %requires wasysym \newcommand{\isasymbox}{\isamath{\Box}} %requires amssymb \newcommand{\isasymdiamond}{\isamath{\Diamond}} %requires amssymb \newcommand{\isasymdiamondop}{\isamath{\diamond}} \newcommand{\isasymsurd}{\isamath{\surd}} \newcommand{\isasymturnstile}{\isamath{\vdash}} \newcommand{\isasymTurnstile}{\isamath{\models}} \newcommand{\isasymtturnstile}{\isamath{\vdash\!\!\!\vdash}} \newcommand{\isasymTTurnstile}{\isamath{\mid\!\models}} \newcommand{\isasymstileturn}{\isamath{\dashv}} \newcommand{\isasymle}{\isamath{\le}} \newcommand{\isasymge}{\isamath{\ge}} \newcommand{\isasymlless}{\isamath{\ll}} \newcommand{\isasymggreater}{\isamath{\gg}} \newcommand{\isasymlesssim}{\isamath{\lesssim}} %requires amssymb \newcommand{\isasymgreatersim}{\isamath{\gtrsim}} %requires amssymb \newcommand{\isasymlessapprox}{\isamath{\lessapprox}} %requires amssymb \newcommand{\isasymgreaterapprox}{\isamath{\gtrapprox}} %requires amssymb \newcommand{\isasymin}{\isamath{\in}} \newcommand{\isasymnotin}{\isamath{\notin}} \newcommand{\isasymsubset}{\isamath{\subset}} \newcommand{\isasymsupset}{\isamath{\supset}} \newcommand{\isasymsubseteq}{\isamath{\subseteq}} \newcommand{\isasymsupseteq}{\isamath{\supseteq}} \newcommand{\isasymsqsubset}{\isamath{\sqsubset}} %requires amssymb \newcommand{\isasymsqsupset}{\isamath{\sqsupset}} %requires amssymb \newcommand{\isasymsqsubseteq}{\isamath{\sqsubseteq}} \newcommand{\isasymsqsupseteq}{\isamath{\sqsupseteq}} \newcommand{\isasyminter}{\isamath{\cap}} \newcommand{\isasymInter}{\isamath{\bigcap\,}} \newcommand{\isasymunion}{\isamath{\cup}} \newcommand{\isasymUnion}{\isamath{\bigcup\,}} \newcommand{\isasymsqunion}{\isamath{\sqcup}} \newcommand{\isasymSqunion}{\isamath{\bigsqcup\,}} \newcommand{\isasymsqinter}{\isamath{\sqcap}} \newcommand{\isasymSqinter}{\isamath{\bigsqcap\,}} %requires stmaryrd \newcommand{\isasymsetminus}{\isamath{\setminus}} \newcommand{\isasympropto}{\isamath{\propto}} \newcommand{\isasymuplus}{\isamath{\uplus}} \newcommand{\isasymUplus}{\isamath{\biguplus\,}} \newcommand{\isasymnoteq}{\isamath{\not=}} \newcommand{\isasymsim}{\isamath{\sim}} \newcommand{\isasymdoteq}{\isamath{\doteq}} \newcommand{\isasymsimeq}{\isamath{\simeq}} \newcommand{\isasymapprox}{\isamath{\approx}} \newcommand{\isasymasymp}{\isamath{\asymp}} \newcommand{\isasymcong}{\isamath{\cong}} \newcommand{\isasymsmile}{\isamath{\smile}} \newcommand{\isasymequiv}{\isamath{\equiv}} \newcommand{\isasymfrown}{\isamath{\frown}} \newcommand{\isasymJoin}{\isamath{\Join}} %requires amssymb \newcommand{\isasymbowtie}{\isamath{\bowtie}} \newcommand{\isasymprec}{\isamath{\prec}} \newcommand{\isasymsucc}{\isamath{\succ}} \newcommand{\isasympreceq}{\isamath{\preceq}} \newcommand{\isasymsucceq}{\isamath{\succeq}} \newcommand{\isasymparallel}{\isamath{\parallel}} \newcommand{\isasymParallel}{\isamath{\bigparallel}} %requires stmaryrd \newcommand{\isasyminterleace}{\isamath{\interleave}} %requires stmaryrd \newcommand{\isasymsslash}{\isamath{\sslash}} %requires stmaryrd \newcommand{\isasymbar}{\isamath{\mid}} \newcommand{\isasymbbar}{\isamath{[\mskip-1.5mu]}} \newcommand{\isasymplusminus}{\isamath{\pm}} \newcommand{\isasymminusplus}{\isamath{\mp}} \newcommand{\isasymtimes}{\isamath{\times}} \newcommand{\isasymdiv}{\isamath{\div}} \newcommand{\isasymcdot}{\isamath{\cdot}} \newcommand{\isasymsqdot}{\isamath{\sbox\z@{$\centerdot$}\ht\z@=.33333\ht\z@\vcenter{\box\z@}}} %requires amssymb \newcommand{\isasymstar}{\isamath{\star}} \newcommand{\isasymbullet}{\boldmath\isamath{\mathchoice{\displaystyle{\cdot}}{\textstyle{\cdot}}{\scriptstyle{\bullet}}{\scriptscriptstyle{\bullet}}}} \newcommand{\isasymcirc}{\isamath{\circ}} \newcommand{\isasymdagger}{\isamath{\dagger}} \newcommand{\isasymddagger}{\isamath{\ddagger}} \newcommand{\isasymlhd}{\isamath{\lhd}} %requires amssymb \newcommand{\isasymrhd}{\isamath{\rhd}} %requires amssymb \newcommand{\isasymunlhd}{\isamath{\unlhd}} %requires amssymb \newcommand{\isasymunrhd}{\isamath{\unrhd}} %requires amssymb \newcommand{\isasymtriangleleft}{\isamath{\triangleleft}} \newcommand{\isasymtriangleright}{\isamath{\triangleright}} \newcommand{\isasymtriangle}{\isamath{\triangle}} \newcommand{\isasymtriangleq}{\isamath{\triangleq}} %requires amssymb \newcommand{\isasymoplus}{\isamath{\oplus}} \newcommand{\isasymOplus}{\isamath{\bigoplus\,}} \newcommand{\isasymotimes}{\isamath{\otimes}} \newcommand{\isasymOtimes}{\isamath{\bigotimes\,}} \newcommand{\isasymodot}{\isamath{\odot}} \newcommand{\isasymOdot}{\isamath{\bigodot\,}} \newcommand{\isasymominus}{\isamath{\ominus}} \newcommand{\isasymoslash}{\isamath{\oslash}} \newcommand{\isasymdots}{\isamath{\dots}} \newcommand{\isasymcdots}{\isamath{\cdots}} \newcommand{\isasymSum}{\isamath{\sum\,}} \newcommand{\isasymProd}{\isamath{\prod\,}} \newcommand{\isasymCoprod}{\isamath{\coprod\,}} \newcommand{\isasyminfinity}{\isamath{\infty}} \newcommand{\isasymintegral}{\isamath{\int\,}} \newcommand{\isasymointegral}{\isamath{\oint\,}} \newcommand{\isasymclubsuit}{\isamath{\clubsuit}} \newcommand{\isasymdiamondsuit}{\isamath{\diamondsuit}} \newcommand{\isasymheartsuit}{\isamath{\heartsuit}} \newcommand{\isasymspadesuit}{\isamath{\spadesuit}} \newcommand{\isasymaleph}{\isamath{\aleph}} \newcommand{\isasymemptyset}{\isamath{\emptyset}} \newcommand{\isasymnabla}{\isamath{\nabla}} \newcommand{\isasympartial}{\isamath{\partial}} \newcommand{\isasymRe}{\isamath{\Re}} \newcommand{\isasymIm}{\isamath{\Im}} \newcommand{\isasymflat}{\isamath{\flat}} \newcommand{\isasymnatural}{\isamath{\natural}} \newcommand{\isasymsharp}{\isamath{\sharp}} \newcommand{\isasymangle}{\isamath{\angle}} \newcommand{\isasymcopyright}{\isatext{\normalfont\rmfamily\copyright}} \newcommand{\isasymregistered}{\isatext{\normalfont\rmfamily\textregistered}} \newcommand{\isasyminverse}{\isamath{{}^{-1}}} \newcommand{\isasymonequarter}{\isatext{\normalfont\rmfamily\textonequarter}} %requires textcomp \newcommand{\isasymonehalf}{\isatext{\normalfont\rmfamily\textonehalf}} %requires textcomp \newcommand{\isasymthreequarters}{\isatext{\normalfont\rmfamily\textthreequarters}} %requires textcomp \newcommand{\isasymordfeminine}{\isatext{\normalfont\rmfamily\textordfeminine}} \newcommand{\isasymordmasculine}{\isatext{\normalfont\rmfamily\textordmasculine}} \newcommand{\isasymsection}{\isatext{\normalfont\rmfamily\S}} \newcommand{\isasymparagraph}{\isatext{\normalfont\rmfamily\P}} \newcommand{\isasymexclamdown}{\isatext{\normalfont\rmfamily\textexclamdown}} \newcommand{\isasymquestiondown}{\isatext{\normalfont\rmfamily\textquestiondown}} \newcommand{\isasymeuro}{\isatext{\euro}} %requires eurosym \newcommand{\isasympounds}{\isamath{\pounds}} \newcommand{\isasymyen}{\isatext{\yen}} %requires amssymb \newcommand{\isasymcent}{\isatext{\textcent}} %requires textcomp \newcommand{\isasymcurrency}{\isatext{\textcurrency}} %requires textcomp \newcommand{\isasymdegree}{\isatext{\normalfont\rmfamily\textdegree}} %requires textcomp \newcommand{\isasymhyphen}{\isatext{\normalfont\rmfamily-}} \newcommand{\isasymamalg}{\isamath{\amalg}} \newcommand{\isasymmho}{\isamath{\mho}} %requires amssymb \newcommand{\isasymlozenge}{\isamath{\lozenge}} %requires amssymb \newcommand{\isasymwp}{\isamath{\wp}} \newcommand{\isasymwrong}{\isamath{\wr}} \newcommand{\isasymacute}{\isatext{\'\relax}} \newcommand{\isasymindex}{\isatext{\i}} \newcommand{\isasymdieresis}{\isatext{\"\relax}} \newcommand{\isasymcedilla}{\isatext{\c\relax}} \newcommand{\isasymhungarumlaut}{\isatext{\H\relax}} \newcommand{\isasymsome}{\isamath{\epsilon\,}} \newcommand{\isasymbind}{\isamath{\mathbin{>\!\!\!>\mkern-6.7mu=}}} \newcommand{\isasymthen}{\isamath{\mathbin{>\!\!\!>}}} %Z notation \newcommand{\isaZhbar}[1]{\rlap{\raise.0001ex\hbox{\isamath{-}}}#1} \newcommand{\isaZpvbar}[1]{\ooalign{\hfil\isamath{\mapstochar\mkern 5mu}\hfil\cr#1}} \newcommand{\isaZfvbar}[1]{\ooalign{\hfil\isamath{\mapstochar\mkern 3mu\mapstochar\mkern 5mu}\hfil\cr#1}} \newcommand{\isaZdarrow}[3]{\ooalign{\isamath{#1}\hfil\cr\isamath{\mkern#3mu\isamath{#2}}}} \newcommand{\isasymZcomp}{\isamath{\fatsemi}} %requires stmaryrd \newcommand{\isasymZinj}{\isamath{\rightarrowtail}} %requires amssymb \newcommand{\isasymZpinj}{\isaZpvbar{\isamath{\rightarrowtail}}} %requires amssymb \newcommand{\isasymZfinj}{\isaZfvbar{\isasymZinj}} %requires amssymb \newcommand{\isasymZsurj}{\isaZdarrow{\rightarrow}{\rightarrow}{4}} %requires amssymb \newcommand{\isasymZpsurj}{\isaZpvbar{\isasymZsurj}} %requires amssymb \newcommand{\isasymZbij}{\isaZdarrow{\rightarrowtail}{\rightarrow}{5}} %requires amssymb \newcommand{\isasymZpfun}{\isaZpvbar{\isamath{\rightarrow}}} \newcommand{\isasymZffun}{\isaZfvbar{\isamath{\rightarrow}}} \newcommand{\isasymZdres}{\isamath{\lhd}} %requires amssymb \newcommand{\isasymZndres}{\isaZhbar{\isamath{\lhd}}} %requires amssymb \newcommand{\isasymZrres}{\isamath{\rhd}} %requires amssymb \newcommand{\isasymZnrres}{\isaZhbar{\isamath{\rhd}}} %requires amssymb \newcommand{\isasymZspot}{\isamath{\bullet}} \newcommand{\isasymZproject}{\isamath{\upharpoonright}} %requires amssymb \newcommand{\isasymZsemi}{\isatext{\raise 0.66ex\hbox{\oalign{\hfil\isamath{\scriptscriptstyle\mathrm{o}}\hfil\cr\hfil\isamath{\scriptscriptstyle\mathrm{9}}\hfil}}}} \newcommand{\isasymZtypecolon}{\isatext{\raise 0.6ex\hbox{\oalign{\hfil\isamath{\scriptscriptstyle\mathrm{o}}\hfil\cr\hfil\isamath{\scriptscriptstyle\mathrm{o}}\hfil}}}} \newcommand{\isasymZhide}{\isamath{\backslash}} \newcommand{\isasymZcat}{\isatext{\raise 0.8ex\hbox{\isamath{\mathchar\frown}}}} \newcommand{\isasymZinbag}{\isatext{\ooalign{\isamath{\sqsubset\mkern-1mu}\cr\isamath{-\mkern-1mu}\cr}}} \newcommand{\isasymhole}{\isatext{\normalfont\rmfamily\wasylozenge}} %requires wasysym \newcommand{\isasymnewline}{\isatext{\fbox{$\hookleftarrow$}}} \newcommand{\isasymcomment}{\isatext{\isastylecmt---}} \newcommand{\isasymproof}{\isamath{\,\langle\mathit{proof}\rangle}} \newcommand{\isasymopen}{\isatext{\guilsinglleft}} \newcommand{\isasymclose}{\isatext{\guilsinglright}} \newcommand{\isasymcheckmark}{\isatext{\ding{51}}} %requires pifont \newcommand{\isasymcrossmark}{\isatext{\ding{55}}} %requires pifont \newcommand{\isactrlmarker}{\isatext{\ding{48}}} %requires pifont \newcommand{\isactrltry}{\isakeywordcontrol{try}} \newcommand{\isactrlcan}{\isakeywordcontrol{can}} \newcommand{\isactrlassert}{\isakeywordcontrol{assert}} \newcommand{\isactrlcancel}{\isakeywordcontrol{cancel}} \newcommand{\isactrlbinding}{\isakeywordcontrol{binding}} \newcommand{\isactrlclass}{\isakeywordcontrol{class}} \newcommand{\isactrlclassUNDERSCOREsyntax}{\isakeywordcontrol{class{\isacharunderscore}syntax}} \newcommand{\isactrlcommandUNDERSCOREkeyword}{\isakeywordcontrol{command{\isacharunderscore}keyword}} \newcommand{\isactrlconst}{\isakeywordcontrol{const}} \newcommand{\isactrlconstUNDERSCOREabbrev}{\isakeywordcontrol{const{\isacharunderscore}abbrev}} \newcommand{\isactrlconstUNDERSCOREname}{\isakeywordcontrol{const{\isacharunderscore}name}} \newcommand{\isactrlconstUNDERSCOREsyntax}{\isakeywordcontrol{const{\isacharunderscore}syntax}} \newcommand{\isactrlcontext}{\isakeywordcontrol{context}} \newcommand{\isactrlcprop}{\isakeywordcontrol{cprop}} \newcommand{\isactrlcterm}{\isakeywordcontrol{cterm}} \newcommand{\isactrlctyp}{\isakeywordcontrol{ctyp}} \newcommand{\isactrldir}{\isakeywordcontrol{dir}} \newcommand{\isactrlfile}{\isakeywordcontrol{file}} \newcommand{\isactrlhere}{\isakeywordcontrol{here}} \newcommand{\isactrlinstantiate}{\isakeywordcontrol{instantiate}} \newcommand{\isactrlkeyword}{\isakeywordcontrol{keyword}} \newcommand{\isactrllatex}{\isakeywordcontrol{latex}} \newcommand{\isactrllocale}{\isakeywordcontrol{locale}} \newcommand{\isactrlmakeUNDERSCOREjudgment}{\isakeywordcontrol{make{\isacharunderscore}judgment}} \newcommand{\isactrldestUNDERSCOREjudgment}{\isakeywordcontrol{dest{\isacharunderscore}judgment}} \newcommand{\isactrlmakeUNDERSCOREstring}{\isakeywordcontrol{make{\isacharunderscore}string}} \newcommand{\isactrlmasterUNDERSCOREdir}{\isakeywordcontrol{master{\isacharunderscore}dir}} \newcommand{\isactrlmethod}{\isakeywordcontrol{method}} \newcommand{\isactrlnamedUNDERSCOREtheorems}{\isakeywordcontrol{named{\isacharunderscore}theorems}} \newcommand{\isactrlnonterminal}{\isakeywordcontrol{nonterminal}} \newcommand{\isactrloracleUNDERSCOREname}{\isakeywordcontrol{oracle{\isacharunderscore}name}} \newcommand{\isactrlpath}{\isakeywordcontrol{path}} \newcommand{\isactrlpathUNDERSCOREbinding}{\isakeywordcontrol{path{\isacharunderscore}binding}} \newcommand{\isactrlplugin}{\isakeywordcontrol{plugin}} \newcommand{\isactrlprint}{\isakeywordcontrol{print}} \newcommand{\isactrlprop}{\isakeywordcontrol{prop}} \newcommand{\isactrlscala}{\isakeywordcontrol{scala}} \newcommand{\isactrlscalaUNDERSCOREfunction}{\isakeywordcontrol{scala{\isacharunderscore}function}} \newcommand{\isactrlscalaUNDERSCOREmethod}{\isakeywordcontrol{scala{\isacharunderscore}method}} \newcommand{\isactrlscalaUNDERSCOREobject}{\isakeywordcontrol{scala{\isacharunderscore}object}} \newcommand{\isactrlscalaUNDERSCOREtype}{\isakeywordcontrol{scala{\isacharunderscore}type}} \newcommand{\isactrlsimproc}{\isakeywordcontrol{simproc}} \newcommand{\isactrlsort}{\isakeywordcontrol{sort}} \newcommand{\isactrlsyntaxUNDERSCOREconst}{\isakeywordcontrol{syntax{\isacharunderscore}const}} \newcommand{\isactrlsystemUNDERSCOREoption}{\isakeywordcontrol{system{\isacharunderscore}option}} \newcommand{\isactrlterm}{\isakeywordcontrol{term}} \newcommand{\isactrltheory}{\isakeywordcontrol{theory}} \newcommand{\isactrltheoryUNDERSCOREcontext}{\isakeywordcontrol{theory{\isacharunderscore}context}} \newcommand{\isactrltyp}{\isakeywordcontrol{typ}} \newcommand{\isactrltypeUNDERSCOREabbrev}{\isakeywordcontrol{type{\isacharunderscore}abbrev}} \newcommand{\isactrltypeUNDERSCOREname}{\isakeywordcontrol{type{\isacharunderscore}name}} \newcommand{\isactrltypeUNDERSCOREsyntax}{\isakeywordcontrol{type{\isacharunderscore}syntax}} \newcommand{\isactrlundefined}{\isakeywordcontrol{undefined}} \newcommand{\isactrltvar}{\isakeywordcontrol{tvar}} \newcommand{\isactrlvar}{\isakeywordcontrol{var}} +\newcommand{\isactrlverbatim}{\isakeywordcontrol{verbatim}} \newcommand{\isactrlConst}{\isakeywordcontrol{Const}} \newcommand{\isactrlConstUNDERSCORE}{\isakeywordcontrol{Const{\isacharunderscore}}} \newcommand{\isactrlConstUNDERSCOREfn}{\isakeywordcontrol{Const{\isacharunderscore}fn}} \newcommand{\isactrlType}{\isakeywordcontrol{Type}} \newcommand{\isactrlTypeUNDERSCOREfn}{\isakeywordcontrol{Type{\isacharunderscore}fn}} \newcommand{\isactrlcode}{\isakeywordcontrol{code}} \newcommand{\isactrlcomputation}{\isakeywordcontrol{computation}} \newcommand{\isactrlcomputationUNDERSCOREconv}{\isakeywordcontrol{computation{\isacharunderscore}conv}} \newcommand{\isactrlcomputationUNDERSCOREcheck}{\isakeywordcontrol{computation{\isacharunderscore}check}} \newcommand{\isactrlifUNDERSCORElinux}{\isakeywordcontrol{if{\isacharunderscore}linux}} \newcommand{\isactrlifUNDERSCOREmacos}{\isakeywordcontrol{if{\isacharunderscore}macos}} \newcommand{\isactrlifUNDERSCOREwindows}{\isakeywordcontrol{if{\isacharunderscore}windows}} \newcommand{\isactrlifUNDERSCOREunix}{\isakeywordcontrol{if{\isacharunderscore}unix}} diff --git a/src/Pure/Tools/build.scala b/src/Pure/Tools/build.scala --- a/src/Pure/Tools/build.scala +++ b/src/Pure/Tools/build.scala @@ -1,655 +1,656 @@ /* Title: Pure/Tools/build.scala Author: Makarius Options: :folding=explicit: Build and manage Isabelle sessions. */ package isabelle import scala.collection.immutable.SortedSet import scala.annotation.tailrec object Build { /** auxiliary **/ /* persistent build info */ sealed case class Session_Info( sources: String, input_heaps: List[String], output_heap: Option[String], return_code: Int, uuid: String ) { def ok: Boolean = return_code == 0 } /* queue with scheduling information */ private object Queue { type Timings = (List[Properties.T], Double) def load_timings(progress: Progress, store: Sessions.Store, session_name: String): Timings = { val no_timings: Timings = (Nil, 0.0) store.try_open_database(session_name) match { case None => no_timings case Some(db) => def ignore_error(msg: String) = { progress.echo_warning("Ignoring bad database " + db + " for session " + quote(session_name) + (if (msg == "") "" else ":\n" + msg)) no_timings } try { val command_timings = store.read_command_timings(db, session_name) val session_timing = store.read_session_timing(db, session_name) match { case Markup.Elapsed(t) => t case _ => 0.0 } (command_timings, session_timing) } catch { case ERROR(msg) => ignore_error(msg) case exn: java.lang.Error => ignore_error(Exn.message(exn)) case _: XML.Error => ignore_error("XML.Error") } finally { db.close() } } } def make_session_timing( sessions_structure: Sessions.Structure, timing: Map[String, Double] ) : Map[String, Double] = { val maximals = sessions_structure.build_graph.maximals.toSet def desc_timing(session_name: String): Double = { if (maximals.contains(session_name)) timing(session_name) else { val descendants = sessions_structure.build_descendants(List(session_name)).toSet val g = sessions_structure.build_graph.restrict(descendants) (0.0 :: g.maximals.flatMap { desc => val ps = g.all_preds(List(desc)) if (ps.exists(p => !timing.isDefinedAt(p))) None else Some(ps.map(timing(_)).sum) }).max } } timing.keySet.iterator.map(name => (name -> desc_timing(name))).toMap.withDefaultValue(0.0) } def apply( progress: Progress, sessions_structure: Sessions.Structure, store: Sessions.Store ) : Queue = { val graph = sessions_structure.build_graph val names = graph.keys val timings = names.map(name => (name, load_timings(progress, store, name))) val command_timings = timings.map({ case (name, (ts, _)) => (name, ts) }).toMap.withDefaultValue(Nil) val session_timing = make_session_timing(sessions_structure, timings.map({ case (name, (_, t)) => (name, t) }).toMap) object Ordering extends scala.math.Ordering[String] { def compare(name1: String, name2: String): Int = session_timing(name2) compare session_timing(name1) match { case 0 => sessions_structure(name2).timeout compare sessions_structure(name1).timeout match { case 0 => name1 compare name2 case ord => ord } case ord => ord } } new Queue(graph, SortedSet(names: _*)(Ordering), command_timings) } } private class Queue( graph: Graph[String, Sessions.Info], order: SortedSet[String], val command_timings: String => List[Properties.T] ) { def is_inner(name: String): Boolean = !graph.is_maximal(name) def is_empty: Boolean = graph.is_empty def - (name: String): Queue = new Queue(graph.del_node(name), order - name, command_timings) def dequeue(skip: String => Boolean): Option[(String, Sessions.Info)] = { val it = order.iterator.dropWhile(name => skip(name) || !graph.is_minimal(name)) if (it.hasNext) { val name = it.next(); Some((name, graph.get_node(name))) } else None } } /** build with results **/ class Results private[Build]( val store: Sessions.Store, + val deps: Sessions.Deps, results: Map[String, (Option[Process_Result], Sessions.Info)], val presentation_sessions: List[String] ) { def cache: Term.Cache = store.cache def sessions: Set[String] = results.keySet def cancelled(name: String): Boolean = results(name)._1.isEmpty def info(name: String): Sessions.Info = results(name)._2 def apply(name: String): Process_Result = results(name)._1.getOrElse(Process_Result(1)) val rc: Int = results.iterator.map({ case (_, (Some(r), _)) => r.rc case (_, (None, _)) => 1 }). foldLeft(Process_Result.RC.ok)(_ max _) def ok: Boolean = rc == Process_Result.RC.ok def unfinished: List[String] = sessions.iterator.filterNot(apply(_).ok).toList.sorted override def toString: String = rc.toString } def session_finished(session_name: String, process_result: Process_Result): String = "Finished " + session_name + " (" + process_result.timing.message_resources + ")" def session_timing(session_name: String, build_log: Build_Log.Session_Info): String = { val props = build_log.session_timing val threads = Markup.Session_Timing.Threads.unapply(props) getOrElse 1 val timing = Markup.Timing_Properties.get(props) "Timing " + session_name + " (" + threads + " threads, " + timing.message_factor + ")" } def build( options: Options, selection: Sessions.Selection = Sessions.Selection.empty, browser_info: Browser_Info.Config = Browser_Info.Config.none, progress: Progress = new Progress, check_unknown_files: Boolean = false, build_heap: Boolean = false, clean_build: Boolean = false, dirs: List[Path] = Nil, select_dirs: List[Path] = Nil, infos: List[Sessions.Info] = Nil, numa_shuffling: Boolean = false, max_jobs: Int = 1, list_files: Boolean = false, check_keywords: Set[String] = Set.empty, fresh_build: Boolean = false, no_build: Boolean = false, soft_build: Boolean = false, verbose: Boolean = false, export_files: Boolean = false, session_setup: (String, Session) => Unit = (_, _) => () ): Results = { val build_options = options + "completion_limit=0" + "editor_tracing_messages=0" + ("pide_reports=" + options.bool("build_pide_reports")) val store = Sessions.store(build_options) Isabelle_Fonts.init() /* session selection and dependencies */ val full_sessions = Sessions.load_structure(build_options, dirs = dirs, select_dirs = select_dirs, infos = infos) val full_sessions_selection = full_sessions.imports_selection(selection) def sources_stamp(deps: Sessions.Deps, session_name: String): String = { val digests = full_sessions(session_name).meta_digest :: deps.session_sources(session_name) ::: deps.imported_sources(session_name) SHA1.digest_set(digests).toString } val build_deps = { val deps0 = Sessions.deps(full_sessions.selection(selection), progress = progress, inlined_files = true, verbose = verbose, list_files = list_files, check_keywords = check_keywords).check_errors if (soft_build && !fresh_build) { val outdated = deps0.sessions_structure.build_topological_order.flatMap(name => store.try_open_database(name) match { case Some(db) => using(db)(store.read_build(_, name)) match { case Some(build) if build.ok && build.sources == sources_stamp(deps0, name) => None case _ => Some(name) } case None => Some(name) }) Sessions.deps(full_sessions.selection(Sessions.Selection(sessions = outdated)), progress = progress, inlined_files = true).check_errors } else deps0 } val build_sessions = build_deps.sessions_structure /* check unknown files */ if (check_unknown_files) { val source_files = (for { (_, base) <- build_deps.session_bases.iterator (path, _) <- base.session_sources.iterator } yield path).toList val exclude_files = List(Path.explode("$POLYML_EXE")).map(_.canonical_file) val unknown_files = Mercurial.check_files(source_files)._2. filterNot(path => exclude_files.contains(path.canonical_file)) if (unknown_files.nonEmpty) { progress.echo_warning("Unknown files (not part of the underlying Mercurial repository):" + unknown_files.map(path => path.expand.implode).sorted.mkString("\n ", "\n ", "")) } } /* main build process */ val queue = Queue(progress, build_sessions, store) store.prepare_output_dir() if (clean_build) { for (name <- full_sessions.imports_descendants(full_sessions_selection)) { val (relevant, ok) = store.clean_output(name) if (relevant) { if (ok) progress.echo("Cleaned " + name) else progress.echo(name + " FAILED to clean") } } } // scheduler loop case class Result( current: Boolean, heap_digest: Option[String], process: Option[Process_Result], info: Sessions.Info ) { def ok: Boolean = process match { case None => false case Some(res) => res.ok } } def sleep(): Unit = Isabelle_Thread.interrupt_handler(_ => progress.stop()) { Time.seconds(0.5).sleep() } val log = build_options.string("system_log") match { case "" => No_Logger case "-" => Logger.make(progress) case log_file => Logger.make(Some(Path.explode(log_file))) } val numa_nodes = new NUMA.Nodes(numa_shuffling) @tailrec def loop( pending: Queue, running: Map[String, (List[String], Build_Job)], results: Map[String, Result] ): Map[String, Result] = { def used_node(i: Int): Boolean = running.iterator.exists( { case (_, (_, job)) => job.numa_node.isDefined && job.numa_node.get == i }) if (pending.is_empty) results else { if (progress.stopped) { for ((_, (_, job)) <- running) job.terminate() } running.find({ case (_, (_, job)) => job.is_finished }) match { case Some((session_name, (input_heaps, job))) => //{{{ finish job val (process_result, heap_digest) = job.join val log_lines = process_result.out_lines.filterNot(Protocol_Message.Marker.test) val process_result_tail = { val tail = job.info.options.int("process_output_tail") process_result.copy( out_lines = "(see also " + store.output_log(session_name).file.toString + ")" :: (if (tail == 0) log_lines else log_lines.drop(log_lines.length - tail max 0))) } val build_log = Build_Log.Log_File(session_name, process_result.out_lines). parse_session_info( command_timings = true, theory_timings = true, ml_statistics = true, task_statistics = true) // write log file if (process_result.ok) { File.write_gzip(store.output_log_gz(session_name), terminate_lines(log_lines)) } else File.write(store.output_log(session_name), terminate_lines(log_lines)) // write database using(store.open_database(session_name, output = true))(db => store.write_session_info(db, session_name, build_log = if (process_result.timeout) build_log.error("Timeout") else build_log, build = Session_Info(sources_stamp(build_deps, session_name), input_heaps, heap_digest, process_result.rc, UUID.random().toString))) // messages process_result.err_lines.foreach(progress.echo) if (process_result.ok) { if (verbose) progress.echo(session_timing(session_name, build_log)) progress.echo(session_finished(session_name, process_result)) } else { progress.echo(session_name + " FAILED") if (!process_result.interrupted) progress.echo(process_result_tail.out) } loop(pending - session_name, running - session_name, results + (session_name -> Result(false, heap_digest, Some(process_result_tail), job.info))) //}}} case None if running.size < (max_jobs max 1) => //{{{ check/start next job pending.dequeue(running.isDefinedAt) match { case Some((session_name, info)) => val ancestor_results = build_sessions.build_requirements(List(session_name)). filterNot(_ == session_name).map(results(_)) val ancestor_heaps = ancestor_results.flatMap(_.heap_digest) val do_store = build_heap || Sessions.is_pure(session_name) || queue.is_inner(session_name) val (current, heap_digest) = { store.try_open_database(session_name) match { case Some(db) => using(db)(store.read_build(_, session_name)) match { case Some(build) => val heap_digest = store.find_heap_digest(session_name) val current = !fresh_build && build.ok && build.sources == sources_stamp(build_deps, session_name) && build.input_heaps == ancestor_heaps && build.output_heap == heap_digest && !(do_store && heap_digest.isEmpty) (current, heap_digest) case None => (false, None) } case None => (false, None) } } val all_current = current && ancestor_results.forall(_.current) if (all_current) { loop(pending - session_name, running, results + (session_name -> Result(true, heap_digest, Some(Process_Result(0)), info))) } else if (no_build) { progress.echo_if(verbose, "Skipping " + session_name + " ...") loop(pending - session_name, running, results + (session_name -> Result(false, heap_digest, Some(Process_Result(1)), info))) } else if (ancestor_results.forall(_.ok) && !progress.stopped) { progress.echo((if (do_store) "Building " else "Running ") + session_name + " ...") store.clean_output(session_name) using(store.open_database(session_name, output = true))( store.init_session_info(_, session_name)) val numa_node = numa_nodes.next(used_node) val job = new Build_Job(progress, session_name, info, build_deps, store, do_store, log, session_setup, numa_node, queue.command_timings(session_name)) loop(pending, running + (session_name -> (ancestor_heaps, job)), results) } else { progress.echo(session_name + " CANCELLED") loop(pending - session_name, running, results + (session_name -> Result(false, heap_digest, None, info))) } case None => sleep(); loop(pending, running, results) } ///}}} case None => sleep(); loop(pending, running, results) } } } /* build results */ val results = { val build_results = if (build_deps.is_empty) { progress.echo_warning("Nothing to build") Map.empty[String, Result] } else Isabelle_Thread.uninterruptible { loop(queue, Map.empty, Map.empty) } val results = (for ((name, result) <- build_results.iterator) yield (name, (result.process, result.info))).toMap val presentation_sessions = (for { name <- build_sessions.build_topological_order.iterator result <- build_results.get(name) if result.ok && browser_info.enabled(result.info) } yield name).toList - new Results(store, results, presentation_sessions) + new Results(store, build_deps, results, presentation_sessions) } if (export_files) { for (name <- full_sessions_selection.iterator if results(name).ok) { val info = results.info(name) if (info.export_files.nonEmpty) { progress.echo("Exporting " + info.name + " ...") for ((dir, prune, pats) <- info.export_files) { Export.export_files(store, name, info.dir + dir, progress = if (verbose) progress else new Progress, export_prune = prune, export_patterns = pats) } } } } if (results.presentation_sessions.nonEmpty && !progress.stopped) { - Browser_Info.build(browser_info, store, build_deps, results.presentation_sessions, + Browser_Info.build(browser_info, results.store, results.deps, results.presentation_sessions, progress = progress, verbose = verbose) } if (!results.ok && (verbose || !no_build)) { progress.echo("Unfinished session(s): " + commas(results.unfinished)) } results } /* Isabelle tool wrapper */ val isabelle_tool = Isabelle_Tool("build", "build and manage Isabelle sessions", Scala_Project.here, { args => val build_options = Word.explode(Isabelle_System.getenv("ISABELLE_BUILD_OPTIONS")) var base_sessions: List[String] = Nil var select_dirs: List[Path] = Nil var numa_shuffling = false var browser_info = Browser_Info.Config.none var requirements = false var soft_build = false var exclude_session_groups: List[String] = Nil var all_sessions = false var build_heap = false var clean_build = false var dirs: List[Path] = Nil var export_files = false var fresh_build = false var session_groups: List[String] = Nil var max_jobs = 1 var check_keywords: Set[String] = Set.empty var list_files = false var no_build = false var options = Options.init(opts = build_options) var verbose = false var exclude_sessions: List[String] = Nil val getopts = Getopts(""" Usage: isabelle build [OPTIONS] [SESSIONS ...] Options are: -B NAME include session NAME and all descendants -D DIR include session directory and select its sessions -N cyclic shuffling of NUMA CPU nodes (performance tuning) -P DIR enable HTML/PDF presentation in directory (":" for default) -R refer to requirements of selected sessions -S soft build: only observe changes of sources, not heap images -X NAME exclude sessions from group NAME and all descendants -a select all sessions -b build heap images -c clean build -d DIR include session directory -e export files from session specification into file-system -f fresh build -g NAME select session group NAME -j INT maximum number of parallel jobs (default 1) -k KEYWORD check theory sources for conflicts with proposed keywords -l list session source files -n no build -- test dependencies only -o OPTION override Isabelle system OPTION (via NAME=VAL or NAME) -v verbose -x NAME exclude session NAME and all descendants Build and manage Isabelle sessions, depending on implicit settings: """ + Library.indent_lines(2, Build_Log.Settings.show()) + "\n", "B:" -> (arg => base_sessions = base_sessions ::: List(arg)), "D:" -> (arg => select_dirs = select_dirs ::: List(Path.explode(arg))), "N" -> (_ => numa_shuffling = true), "P:" -> (arg => browser_info = Browser_Info.Config.make(arg)), "R" -> (_ => requirements = true), "S" -> (_ => soft_build = true), "X:" -> (arg => exclude_session_groups = exclude_session_groups ::: List(arg)), "a" -> (_ => all_sessions = true), "b" -> (_ => build_heap = true), "c" -> (_ => clean_build = true), "d:" -> (arg => dirs = dirs ::: List(Path.explode(arg))), "e" -> (_ => export_files = true), "f" -> (_ => fresh_build = true), "g:" -> (arg => session_groups = session_groups ::: List(arg)), "j:" -> (arg => max_jobs = Value.Int.parse(arg)), "k:" -> (arg => check_keywords = check_keywords + arg), "l" -> (_ => list_files = true), "n" -> (_ => no_build = true), "o:" -> (arg => options = options + arg), "v" -> (_ => verbose = true), "x:" -> (arg => exclude_sessions = exclude_sessions ::: List(arg))) val sessions = getopts(args) val progress = new Console_Progress(verbose = verbose) val start_date = Date.now() if (verbose) { progress.echo( "Started at " + Build_Log.print_date(start_date) + " (" + Isabelle_System.getenv("ML_IDENTIFIER") + " on " + Isabelle_System.hostname() +")") progress.echo(Build_Log.Settings.show() + "\n") } val results = progress.interrupt_handler { build(options, selection = Sessions.Selection( requirements = requirements, all_sessions = all_sessions, base_sessions = base_sessions, exclude_session_groups = exclude_session_groups, exclude_sessions = exclude_sessions, session_groups = session_groups, sessions = sessions), browser_info = browser_info, progress = progress, check_unknown_files = Mercurial.is_repository(Path.ISABELLE_HOME), build_heap = build_heap, clean_build = clean_build, dirs = dirs, select_dirs = select_dirs, numa_shuffling = NUMA.enabled_warning(progress, numa_shuffling), max_jobs = max_jobs, list_files = list_files, check_keywords = check_keywords, fresh_build = fresh_build, no_build = no_build, soft_build = soft_build, verbose = verbose, export_files = export_files) } val end_date = Date.now() val elapsed_time = end_date.time - start_date.time if (verbose) { progress.echo("\nFinished at " + Build_Log.print_date(end_date)) } val total_timing = results.sessions.iterator.map(a => results(a).timing).foldLeft(Timing.zero)(_ + _). copy(elapsed = elapsed_time) progress.echo(total_timing.message_resources) sys.exit(results.rc) }) /* build logic image */ def build_logic(options: Options, logic: String, progress: Progress = new Progress, build_heap: Boolean = false, dirs: List[Path] = Nil, fresh: Boolean = false, strict: Boolean = false ): Int = { val selection = Sessions.Selection.session(logic) val rc = if (!fresh && build(options, selection = selection, build_heap = build_heap, no_build = true, dirs = dirs).ok) Process_Result.RC.ok else { progress.echo("Build started for Isabelle/" + logic + " ...") Build.build(options, selection = selection, progress = progress, build_heap = build_heap, fresh_build = fresh, dirs = dirs).rc } if (strict && rc != Process_Result.RC.ok) error("Failed to build Isabelle/" + logic) else rc } }