read(`code_finsubgames.txt`): Help_paper:=proc() print(` WritePaper(outfile, files, descs, argseq, opts:={}) `): print(` ProvePeriodAndPrefix(S, opts:={}) `): print(` WritePrefPerPaper(Slist,outfile,opts:={}) `): print(` WriteSelfContainedPaper(Slist,outfile,title,author,opts:={},descr:=false) `): print(` WriteSelfContainedPaperFromDBFile(filter,infile,outfile,title,author,opts:={},stopcond:=false) `): end: #Write a paper, automatically! #Arugments: #outfile: The file where the paper is to be output #files: A list of files to work with (in a specific order) #descs: A list of descriptions, one for each file in files #Entries can be false if you want no description #argseq: A list of lists of six-element lists. #The six elements are, in order, #A list of filters used for counts #A list of filters used for averages #A list of selectors used for averages #A list of filters used for extracts #A list of selectors used for extracts #A stop condition for that iteration #Each sublist corresponds to a file in files #opts: a set of options #Available options: "FLOAT" WritePaper:=proc(outfile, files, descs, argseq, opts:={}) local ofd,file,fd,entry, countfilters,avgfilters,avgselectors,extfilters, extselectors,stopcond,data,first,datum,i,str,j: try: ofd:=fopen(outfile,WRITE): for i from 1 to nops(files) do: file:=files[i]: fd:=OpenDB(file): ResetDB(fd): for entry in argseq[i] do countfilters:=entry[1]: avgfilters:=entry[2]: avgselectors:=entry[3]: extfilters:=entry[4]: extselectors:=entry[5]: stopcond:=entry[6]: data:=ParallelCountAverageExtractFileNoReset(file, countfilters,avgfilters,avgselectors, extfilters,extselectors,stopcond): first:=true: #Counts for j from 1 to nops(data[1]) do datum:=data[1][j]: if not first then fprintf(ofd, "%s", " "): fi: first:=false: if datum=1 then str:="There is ": str:=cat(str,convert(datum,string)): str:=cat(str," subtraction game "): if descs[i] != false then str:=cat(str," with "): str:=cat(str,descs[i]): fi: else str:="There are ": str:=cat(str,convert(datum,string)): str:=cat(str," subtraction games "): if descs[i] != false then str:=cat(str," with "): str:=cat(str,descs[i]): fi: fi: str:=cat(str,countfilters[j](0,0,0,0,0,0)): str:=cat(str,"."): fprintf(ofd,"%s",str): od: if not first then fprintf(ofd, "%s", "\n\n"): fi: first:=true: #Averages for j from 1 to nops(data[2]) do datum:=data[2][j]: if not first then fprintf(ofd, "%s", " "): fi: first:=false: str:="The average ": str:=cat(str,avgselectors[j](0,0,0,0,0,0)): str:=cat(str," of subtraction games "): if descs[i] != false then str:=cat(str," with "): str:=cat(str,descs[i]): fi: str:=cat(str,avgfilters[j](0,0,0,0,0,0)): str:=cat(str," is "): if datum=FAIL then str:=cat(str,"undefined"): else if "FLOAT" in opts then str:=cat(str,convert(evalf(datum), string)): else str:=cat(str,convert(datum,string)): fi: fi: str:=cat(str,"."): fprintf(ofd,"%s",str): od: if not first then fprintf(ofd, "%s", "\n\n"): fi: first:=true: #Extracts for j from 1 to nops(data[3]) do datum:=data[3][j]: if not first then fprintf(ofd, "%s", " "): fi: first:=false: str:="The ": str:=cat(str,extselectors[j](0,0,0,0,0,0)): str:=cat(str," of subtraction games "): if descs[i] != false then str:=cat(str," with "): str:=cat(str,descs[i]): fi: str:=cat(str,extfilters[j](0,0,0,0,0,0)): str:=cat(str," are "): str:=cat(str,convert(datum,string)): str:=cat(str,"."): fprintf(ofd,"%s",DequoteString(str)): od: if not first then fprintf(ofd, "%s", "\n\n"): fi: od: od: finally: fclose(ofd): end try: end: #Write a "Theorem" and "Proof" of the period and prefix #for subtraction set S #Returns the output as a two element sequence thm,proof #(so you can number it manually) #Options is a set of options #Available options: #"DETAILED": don't abbreviate things like "minimum excluded #element" (mex), etc. #"VERBOSE": it might return a really long proof #"LATEX": it gives LaTeX-formatted output #"DISPLAY": does nothing unless "LATEX" also specified, in which #case it puts certain LaTeX into display mode #"NICEHBOX": does nothing unless "LATEX" also specified, in which #case it tries really hard not to overflow hboxes. You can #include a number after NICEHBOX, i.e. "NICEHBOX20", to force #line breaks to occur (approximately) after that many #(20) characters. ProvePeriodAndPrefix:=proc(S, opts:={}) local period, prefix, thm, pf, ms, plen, pflen, reps, Latex, i, j, T, sq, nichebox, opt,hlimit: hlimit:=false: for opt in opts do if opt = "NICEHBOX" then hlimit:=75: break: elif length(opt) > 8 and opt[1..8] = "NICEHBOX" then hlimit:=parse(opt[9..-1]): break: fi: od: Latex:=proc(str, display:=false) local ret,escme,ret2,k,l,initial: if "LATEX" in opts then ret:=Substitute(str, "in", "\\in"): ret:=Substitute(ret, "{", "\\left\\{"): ret:=Substitute(ret, "}", "\\right\\}"): if "DISPLAY" in opts and display then if hlimit <> false then #Avoid magic numbers! ret2:=ToLatexArray(ret, hlimit): else ret2:=ret: fi: ret:=cat("\\[", ret2, "\\]"): else if hlimit <> false and display then #Avoid magic numbers! ret2:="": l:=0: for k from 1 to length(ret) do ret2:=cat(ret2,ret[k]): l:=l+1: if l >= hlimit and ret[k] = " " then l:=0: ret2:=cat(ret2, "$ $"): fi: od: else ret2:=ret: fi: ret:=cat("$", ret2, "$"): fi: ret:=Substitute(ret, ".$", "$."): return ret: else return str: fi: end: period,prefix:=GetPeriodAndPrefix(S): pflen:=nops(prefix): if pflen > 0 then thm:=cat("The Nim sequence for subtraction set ", Latex(convert(S,string)), " begins with ", Latex(convert(prefix,string)[2..-2], true), " and then consists of ", Latex(convert(period,string)[2..-2], true), " repeating forever."): else thm:=cat("The Nim sequence for subtraction set ", Latex(convert(S,string)), " consists of ", Latex(convert(period,string)[2..-2], true), " repeating forever."): fi: if nops(S) = 0 then pf:="No moves are every possible, so all Nim values are zero.": return thm,pf: fi: ms:=max(S): plen:=nops(period): reps:=ceil(ms/plen) + 1: pf:=cat("Consider the sequence ", Latex(cat(Join([convert(period,string)[2..-2]$reps], ", ") , "."), true), " This is our proposed period repeated ", Latex(convert(reps,string)), " times. "): if "VERBOSE" in opts then for i from ms + 1 to reps * plen do pf:=cat(pf, "Element number ", Latex(convert(i,string)), " (value ", Latex(convert(period[MapleMod(i,plen)],string)), ") is the "): if "DETAILED" in opts then pf:=cat(pf, "minimum excluded element"): else pf:=cat(pf, "mex"): fi: pf:=cat(pf, " of "): for j from 1 to nops(S) - 1 do pf:=cat(pf, " element number ", Latex(cat(convert(i,string), "-", convert(S[j],string), "=", convert(i-S[j],string))), " (value ", Latex(convert(period[MapleMod(i-S[j],plen)] ,string)), "), "): od: j:=nops(S): pf:=cat(pf, " and element number ", Latex(cat(convert(i,string), "-", convert(S[j],string), "=", convert(i-S[j],string))), " (value ", Latex(convert(period[MapleMod(i-S[j],plen)] ,string)), "). "): od: else pf:=cat(pf, "This sequence has the property that ", "every entry in position ", Latex("n"), " where ", Latex(cat("n > ", convert(ms,string))), " is the "): if "DETAILED" in opts then pf:=cat(pf, "minimum excluded element"): else pf:=cat(pf, "mex"): fi: pf:=cat(pf, " of the set of entries whose positions are ", "of the form ", Latex("n-s"), " for some ", Latex(cat("s in ", convert(S,string))), ". "): fi: pf:=cat(pf,"This covers more than an entire period, so our ", "proposed eventual period occurs in the Nim ", "sequence for the given subtraction set if we can ", "show that this sequence occurs in that Nim ", "sequence.\n\n"): if "VERBOSE" in opts then pf:=cat(pf, "Now, we compute the first ", Latex(convert(pflen+reps*plen,string)), " entries in the Nim sequence for ", "subtraction set ", Latex(convert(S,string)), ". "): sq:=prefix: for i from 1 to reps do sq:=[op(sq), op(period)]: od: for i from 1 to pflen+reps*plen do pf:=cat(pf, "Element number ", Latex(convert(i,string)), " is the "): if "DETAILED" in opts then pf:=cat(pf, "minimum excluded element"): else pf:=cat(pf, "mex"): fi: T:={}: for j in S do if j < i then T:=T union {j}: fi: od: if nops(T) = 0 then pf:=cat(pf, " of the empty set, so its value is ", Latex(convert(0,string)),". "): elif nops(T) = 1 then pf:=cat(pf, " of element number ", Latex(cat(convert(i,string), "-", convert(T[1],string), "=", convert(i-T[1],string))), " (value ", Latex(convert(sq[i-T[1]],string)), "), so its value is ", Latex(convert(sq[i],string)), ". "): else pf:=cat(pf, " of"): for j from 1 to nops(T) - 1 do pf:=cat(pf, " element number ", Latex(cat(convert(i,string), "-", convert(T[j],string), "=", convert(i-T[j],string))), " (value ", Latex(convert(sq[i-T[j]],string)), "), "): od: j:=nops(T): pf:=cat(pf, " and element number ", Latex(cat(convert(i,string), "-", convert(T[j],string), "=", convert(i-T[j],string))), " (value ", Latex(convert(sq[i-T[j]],string)), "), so its value is ", Latex(convert(sq[i],string)), ". "): fi: od: else pf:=cat(pf, "Now, we note that the first ", Latex(convert(pflen+reps*plen,string)), " entries in the Nim sequence for ", "subtraction set ", Latex(convert(S,string)), " are "): if pflen > 0 then pf:=cat(pf, Latex(cat(convert(prefix,string)[2..-2], ", ", Join([convert(period,string)[2..-2]$reps], ", "), "."), true), " "): else pf:=cat(pf, Latex(cat( Join([convert(period,string)[2..-2]$reps], ", "), "."), true), " "): fi: fi: if pflen > 0 then pf:=cat(pf, "This ends with the sequence we ", "considered, and it begins with our proposed ", "prefix. Therefore, the Nim sequence for ", "subtraction set ", Latex(convert(S,string)), " has the desired prefix and eventual period."): else pf:=cat(pf, "This is precisely the sequence ", "we considered. Therefore, the Nim sequence ", "for subtraction set ", Latex(convert(S,string)), " has the desired period."): fi: return thm,pf: end: #Write a paper using multiple calls to ProvePeriodAndPrefix #Outfile can be terminal or a file #opts can be same as in ProvePeriodAndPrefix #LaTeX mode assume you have amsthm in your environment, #With theorem and proof as defined \newtheorem's #Another option is "STRING", which ignores the argument #outfile and instead returns the paper as a string WritePrefPerPaper:=proc(Slist,outfile,opts:={}) local ofd, thms, pfs, S, thm, pf, i, ret: thms:=[]: pfs:=[]: for S in Slist do thm,pf:=ProvePeriodAndPrefix(S, opts): thms:=[op(thms), thm]: pfs:=[op(pfs), pf]: od: if "STRING" in opts then ret:="": elif outfile = terminal then ofd:=terminal else ofd:=fopen(outfile, WRITE): end: for i from 1 to nops(thms) do if "STRING" in opts then if "LATEX" in opts then ret:=cat(ret, sprintf("%s", "\\begin{theorem}\n")): else ret:=cat(ret, sprintf("%s%d:\n", "Theorem ", i)): fi: ret:=cat(ret, sprintf("%s\n", thms[i])): if "LATEX" in opts then ret:=cat(ret, sprintf("%s", "\\end{theorem}\n\\begin{proof}\n")): else ret:=cat(ret, sprintf("%s:\n", "\nProof")): fi: ret:=cat(ret, sprintf("%s\n", pfs[i])): if "LATEX" in opts then ret:=cat(ret, sprintf("%s", "\\end{proof}\n")): else ret:=cat(ret, sprintf("%s", "\n")): fi: else: if "LATEX" in opts then fprintf(ofd, "%s", "\\begin{theorem}\n"): else fprintf(ofd, "%s%d:\n", "Theorem ", i): fi: fprintf(ofd, "%s\n", thms[i]): if "LATEX" in opts then fprintf(ofd, "%s", "\\end{theorem}\n\\begin{proof}\n"): else fprintf(ofd, "%s:\n", "\nProof"): fi: fprintf(ofd, "%s\n", pfs[i]): if "LATEX" in opts then fprintf(ofd, "%s", "\\end{proof}\n"): else fprintf(ofd, "%s", "\n"): fi: fi: od: if "STRING" in opts then return ret: elif outfile <> terminal then fclose(ofd): fi: end: #Write a paper using multiple calls to ProvePeriodAndPrefix #Outfile can be terminal or a file #opts can be same as in ProvePeriodAndPrefix, except that LATEX #is automatically applied #Additional options include "INTRO", which writes an introduction, #"INSTRUCTIVE", which doesn't prove all of the given sets, but #chooses random ones while trying to choose instructively #If you want to force a certain number of proofs, include the #number at the end of the word INSTRUCTIVE, such as "INSTRUCTIVE3" #"RANDOM", which doesn't prove all of the given sets, but #chooses random ones #If you want to force a certain number of proofs, include the #number at the end of the word RANDOM, such as "RANDOM3" #"RANDOM" has no effect if "INSTRUCTIVE" is also present, #unless it defines a number and "INSTRUCTIVE" does not. Then, #"RANDOM"'s number gets used (as if it were defined by #"INSTRUCTIVE") #If you define multiples of either of these, the behavior is #undefined #"SUMMARY", which includes a summary of results #"SORTED", which sorts the sets in colexicographic order #If either "INSTRUCTIVE" or "RANDOM" is present, then "SORTED" #does nothing, as it is automatically applied. If "SORTED" is #absent, sets appear in the order they appear in Slist #"SORTED" also applies to the summary, if it exists #"NODATE" does not include today's date #"SUMMNICEHBOX" does nothing if "SUMMARY" is not included. #Otherwise, it behaves identically to "NICEHBOX" (even with #regard to a number added on!), but it applies to the summary #section as opposed to the proofs # #descr is a description of what's in the paper. It is only used #if "INTRO" is used. If it is false, no description is used. #It should be of the same grammatical structure as the description #returned by a filter WriteSelfContainedPaper:=proc(Slist,outfile,title,author,opts:={},descr:=false) local paper, ofd, preamble, Slist2, opt, sct, rlev, SShuff, i, Colex, Slpref, lpref, Slper, lper, S, period, prefix, intro, bib, summ, Slist3, hlimit, perstr, prefstr, ret, ok, extra: Colex:=proc(s1, s2) local ss1, ss2, m1, m2: ss1:=s1: ss2:=s2: while nops(ss1) > 0 and nops(ss2) > 0 do m1:=max(ss1): m2:=max(ss2): if m1 < m2 then return true: elif m1 > m2 then return false: fi: ss1:=ss1 minus {m1}: ss2:=ss2 minus {m2}: od: return false: end: sct:=false: rlev:=0: Slist3:=Slist: hlimit:=false: for opt in opts do if opt = "INSTRUCTIVE" then rlev:=2: elif length(opt) > 11 and opt[1..11] = "INSTRUCTIVE" then rlev:=2: sct:=parse(opt[12..-1]): elif opt = "RANDOM" then rlev:=max(rlev, 1): elif length(opt) > 6 and opt[1..6] = "RANDOM" then rlev:=max(rlev, 1): if sct = false then sct:=parse(opt[7..-1]): fi: elif opt = "SUMMNICEHBOX" then hlimit:=20: elif length(opt) > 12 and opt[1..12] = "SUMMNICEHBOX" then hlimit:=parse(opt[13..-1]): fi: od: if rlev = 1 then if sct = false then sct:=ceil(log(nops(Slist))): fi: Slist2:=[]: SShuff:=Shuffle(Slist): for i from 1 to min(sct, nops(Slist)) do Slist2:=[op(Slist2), SShuff[i]]: od: Slist2:=sort(Slist2, Colex): if "SORTED" in opts then Slist3:=sort(Slist, Colex): fi: elif rlev = 2 then if sct = false then sct:=ceil(log(nops(Slist))): fi: lpref:=0: lper:=-1: Slpref:={"x"}: ok:=true: for S in Slist do period,prefix:=GetPeriodAndPrefix(S): if nops(period) > lper then Slper:=S: lper:=nops(period): ok:=evalb(nops(prefix) = 0): fi: if nops(prefix) > lpref then Slpref:=S: lpref:=nops(prefix): fi: od: Slist2:=[Slper]: if lpref > 0 and Slper <> Slpref then Slist2:=[op(Slist2), Slpref]: fi: if sct = 1 and nops(Slist2) = 2 then Slist2:=[Slpref]: fi: extra:=false: if nops(Slist2) < sct then SShuff:=Shuffle(Slist): for i from 1 to nops(Slist) do if nops(Slist2) = sct - 1 and not ok and SShuff[i] <> Slpref and SShuff[i] <> Slper then period,prefix:=GetPeriodAndPrefix(SShuff[i]): if nops(prefix) = 0 then Slist2:=[op(Slist2), SShuff[i]]: elif extra = false then extra:=SShuff[i]: fi: elif SShuff[i] <> Slpref and SShuff[i] <> Slper then Slist2:=[op(Slist2), SShuff[i]]: fi: if nops(Slist2) >= sct then break: fi: od: fi: if nops(Slist2) < sct and extra <> false then Slist2:=[op(Slist2), extra]: fi: Slist2:=sort(Slist2, Colex): if "SORTED" in opts then Slist3:=sort(Slist, Colex): fi: elif "SORTED" in opts then Slist2:=sort(Slist, Colex): Slist3:=Slist2: else Slist2:=Slist: fi: paper:=WritePrefPerPaper(Slist2,outfile,opts union {"LATEX", "STRING"}): if "STRING" in opts then ret:="": elif outfile = terminal then ofd:=terminal else ofd:=fopen(outfile, WRITE): end: preamble:="": preamble:=cat(preamble, "\\documentclass[12pt,letterpaper]{article}\n"): preamble:=cat(preamble, "\\usepackage{amsthm}\n"): if "INTRO" in opts then preamble:=cat(preamble, "\\usepackage{amsrefs}\n"): fi: if "SUMMARY" in opts then preamble:=cat(preamble, "\\usepackage{longtable}\n"): fi: preamble:=cat(preamble, "\\newtheorem{theorem}{Theorem}\n"): if "INTRO" in opts then preamble:=cat(preamble, "\\newtheorem{defin}{Definition}\n"): fi: preamble:=cat(preamble, "\\title{"): preamble:=cat(preamble, title): preamble:=cat(preamble, "}\n"): preamble:=cat(preamble, "\\author{"): preamble:=cat(preamble, author): preamble:=cat(preamble, "}\n"): if "NODATE" in opts then preamble:=cat(preamble, "\\date{}\n"): fi: preamble:=cat(preamble, "\\begin{document}\n\n"): preamble:=cat(preamble, "\\maketitle\n\n"): if "STRING" in opts then ret:=cat(ret, preamble): else fprintf(ofd, "%s", preamble): fi: if "INTRO" in opts then intro:="\\section{Introduction}\n": intro:=cat(intro, "We begin with the following definition:\n"): intro:=cat(intro, "\\begin{defin}\n"): intro:=cat(intro, "A \\emph{subtraction game} is a counter-removing game where the legal moves consist of removing exactly some number of counters in a set $S$, called the \\emph{subtraction set}. The first player to be unable to move loses.\n"): intro:=cat(intro, "\\end{defin}"): intro:=cat(intro, "One can consider subtraction games whose subtraction sets are either finite or infinite. We will only consider the finite case here.\n\n"): intro:=cat(intro, "We will also need the following definition:\n"): intro:=cat(intro, "\\begin{defin}\n"): intro:=cat(intro, "The \\emph{Sprague-Grundy function} of a position in a subtraction game is defined to be zero if the position has no legal moves, and it is the minimal excluded nonnegative integer (mex) of the Sprague-Grundy function values of all positions reachable from the current position otherwise.\n"): intro:=cat(intro, "\\end{defin}\n"): intro:=cat(intro, "For a given subtraction set $S$, we define the \\emph{Sprague-Grundy sequence}, or \\emph{Nim sequence}, of $S$ to be the sequence of values the Sprague-Grundy function takes on $0$, $1$, $2$, etc. counters with subtraction set $S$.\n\n"): intro:=cat(intro, "It is well known that, if $S$ is finite, then the Nim sequence of $S$ is eventually periodic~\\cite{bcg}. We will call the period of the period part of such a Nim sequence the \\emph{period} of the Nim sequence, and we will call the shortest possible prefix such that the remainder is periodic the \\emph{prefix} of the Nim sequence. Beyond this fact about periodicity, very little is known about general subtraction sets. "): if descr = false then intro:=cat(intro, "In this paper, we compute the periods and prefixes of the Nim sequences of certain subtraction games. "): else intro:=cat(intro, "In this paper, we compute the periods and prefixes of the Nim sequences of subtraction games ", descr, ". "): if Search("contraction", descr) > 0 then intro:=cat(intro, "(We say that a subtraction set $S$ is a contraction of another set $T$ if $S\\subset T$ and $S$ and $T$ have the same Nim sequence.) "): fi: fi: if "SUMMARY" in opts then intro:=cat(intro, "In Section~\\ref{sec:sum}, we give a table illustrating all of our data. "): if rlev = 0 then intro:=cat(intro, "Then, in Section~\\ref{sec:pfs}, we give a proof of each of these results.\n"): else intro:=cat(intro, "Then, in Section~\\ref{sec:pfs}, we give a proof of a selection of these results.\n"): fi: intro:=cat(intro, "\\section{Results}\\label{sec:sum}\n"): else if rlev = 0 then intro:=cat(intro, "Then, in Section~\\ref{sec:pfs}, we state and prove our results.\n"): else intro:=cat(intro, "Then, in Section~\\ref{sec:pfs}, we state and prove a selection of our results.\n"): fi: intro:=cat(intro, "\\section{Proofs}\\label{sec:pfs}\n"): fi: if "STRING" in opts then ret:=cat(ret, intro): else fprintf(ofd, "%s", intro): fi: fi: if "SUMMARY" in opts then if rlev = 0 then summ:="Here is a concise representation of our results.\n\n": else summ:="Here is a concise representation of our results. Proofs of a selection of these appear in the next section.\n\n": fi: summ:=cat(summ, "\\begin{center}\n"): summ:=cat(summ, "\\begin{longtable}{|l|l|l|}\n"): summ:=cat(summ, "\\hline \\multicolumn{1}{|c|}{\\textbf{Subtraction Set}} & \\multicolumn{1}{c|}{\\textbf{Prefix}} & \\multicolumn{1}{c|}{\\textbf{Eventual Period}} \\\\ \\hline\n"): summ:=cat(summ, "\\endfirsthead\n\n"): summ:=cat(summ, "\\multicolumn{3}{c}\n"): summ:=cat(summ, "{{Continued from previous page}} \\\\\n"): summ:=cat(summ, "\\hline \\multicolumn{1}{|c|}{\\textbf{Subtraction Set}} & \\multicolumn{1}{c|}{\\textbf{Prefix}} & \\multicolumn{1}{c|}{\\textbf{Eventual Period}} \\\\ \\hline\n"): summ:=cat(summ, "\\endhead\n\n"): summ:=cat(summ, "\\hline \\multicolumn{3}{|r|}{{Continued on next page}} \\\\ \\hline\n"): summ:=cat(summ, "\\endfoot\n\n"): summ:=cat(summ, "\\hline \n"): summ:=cat(summ, "\\endlastfoot\n\n"): for S in Slist3 do period,prefix:=GetPeriodAndPrefix(S): perstr:=convert(period, string)[2..-2]: if hlimit <> false then perstr:=ToLatexArray(perstr, hlimit, false): fi: if nops(prefix) = 0 then summ:=cat(summ, "$\\left\\{", convert(S, string)[2..-2], "\\right\\}$ & (none) & $", perstr, "$\\\\\\hline\n"): else prefstr:=convert(prefix, string)[2..-2]: if hlimit <> false then prefstr:=ToLatexArray(prefstr, hlimit, false): fi: summ:=cat(summ, "$\\left\\{", convert(S, string)[2..-2], "\\right\\}$ & $", prefstr, "$ & $", perstr, "$\\\\\\hline\n"): fi: od: summ:=cat(summ, "\\end{longtable}\n"): summ:=cat(summ, "\\end{center}\n\\section{Proofs}\\label{sec:pfs}\n"): if "STRING" in opts then ret:=cat(ret, summ): else fprintf(ofd, "%s", summ): fi: fi: if "STRING" in opts then ret:=cat(ret, paper): else fprintf(ofd, "%s", paper): fi: if "INTRO" in opts then bib:="\n\\begin{bibdiv}\n": bib:=cat(bib, "\\begin{biblist}\n"): bib:=cat(bib, "\\bib{bcg}{book}\n"): bib:=cat(bib, "{\n"): bib:=cat(bib, " author = {Berlekamp, E. R.},\n"): bib:=cat(bib, " author = {Conway, J. H.},\n"): bib:=cat(bib, " author = {Guy, R. K.},\n"): bib:=cat(bib, " title = {Winning Ways for Your Mathematical Plays},\n"): bib:=cat(bib, " volume = {1},\n"): bib:=cat(bib, " publisher = {A. K. Peters},\n"): bib:=cat(bib, " year = {2001}\n"): bib:=cat(bib, "}\n"): bib:=cat(bib, "\\end{biblist}\n"): bib:=cat(bib, "\\end{bibdiv}"): if "STRING" in opts then ret:=cat(ret, bib): else fprintf(ofd, "%s", bib): fi: fi: if "STRING" in opts then ret:=cat(ret, "\n\\end{document}"): return ret: else fprintf(ofd, "%s", "\n\\end{document}"): fi: if outfile <> terminal then fclose(ofd): fi: end: #Write a self-contained paper from a DB file, infile #opts are the same as in WriteSelfContainedPaper #filter is the filter to apply to infile to figure out which #sets to include in the paper #e.g. use PrimitiveFilter to extend Winning Ways's table #additional option: "NORESET" will not reset the DB file #before reading, and it will stop once stopcond is met #once and not met again. stopcond is only considered as an #argument if "NORESET" is passed as an option. Even then, if #it is omitted (or set to false), it default to filter WriteSelfContainedPaperFromDBFile:=proc(filter,infile,outfile,title,author,opts:={},stopcond:=false) local Slist: if "NORESET" in opts then Slist:=ExtractFileNoReset(infile,filter, SSelector,stopcond): else Slist:=ExtractFile(infile, filter, SSelector): fi: WriteSelfContainedPaper(Slist, outfile, title, author, opts, filter(0,0,0,0,0,0)): end: