Erstellung von Rechenbäumen

Beschreibung

Damit ich nicht immer in LaTeX Rechenbäume von Hand estellen muss, haben Stephan und ich uns hingesetzt und ein kleines awk-Skript geschrieben. Dies Skript erstellt für vollständig geklammerte Terme einen Rechenbaum mit XY-Pic. Dafür benötigt man in seinem LaTeX-Kopf das Paket xy (siehe http://www.ctan.org/ctan/tex-archive/macros/generic/diagrams/xypic/)

awk gibt es entweder unter Linux, oder muss man sich unter Windows installieren. Dies kann man sich unter http://gnuwin32.sourceforge.net/packages/gawk.htm herunterladen.

Für das Skript gibt es zwei Parameter. Zum einen den Parameter solve und zum Anderen den Parameter include. Möchte man den Rechenbaum in eine schon vorhandene LaTeX-Datei einfügen, so setzt man den Parameter include auf 1, ansonsten auf 0. Mit solve=0 erhält man einen leeren Rechenbaum. Mit solve=1 erhält man einen Rechenbaum mit Lösung. Erstellt man eine LaTeX-Datei ohne Kopf, so muss man in das LaTeX-Dokument das Paket

Beispiel

Als vollständig geklammerten Term gebe ich ((112-(4*(25-17)))+48) in der Datei test.txt ein. Für einen leeren Baum gebe ich auf der Kommandozeile den folgenden Aufruf ein:

awk -f rechenbaum.awk -v solve=0 -v include=1 test.txt > test.tex

In der test.tex steht dann das Folgende:

 test.tex 
% ((112-(4*(25-17)))+48) \scalebox{0.8}{ \centerline{\xymatrix@R=5pt{ 112\ar@{-} '[4,0]+0 `d[5,1] [5,1]&&4\ar@{-} '[2,0]+0 `d[3,1] [3,1]&& 25\ar@{-} `d[1,1] [1,1]&&17\ar@{-} `d[1,-1] [1,-1]&&48\ar@{-} '[6,0]+0 `d[7,- 1] [7,-1]& \\ &&&&&*+[o][F]{-}\ar@{-}[d]&&&& \\ &&&&&*+[F]{\makebox(30,10){}}\ar@{-} `d[1,-2] [1,-2]&&&& \\ &&&*+[o][F]{\txt{$\cdot$}}\ar@{-}[d]&&&&&& \\ &&&*+[F]{\makebox(30,10){}}\ar@{-} `d[1,-2] [1,-2]&&&&&& \\ &*+[o][F]{-}\ar@{-}[d]&&&&&&&& \\ &*+[F]{\makebox(30,10){}}\ar@{-} `d[1,6] [1,6]&&&&&&&& \\ &&&&&&&*+[o][F]{+}\ar@{-}[d]&& \\ &&&&&&&*+[F]{\makebox(30,10){}}&& } } }

Für einen Baum mit Lösung gebe ich auf der Kommandozeile den folgenden Aufruf ein:

awk -f rechenbaum.awk -v solve=1 -v include=1 test.txt > test.s.tex
 test.s.tex 
% ((112-(4*(25-17)))+48) \scalebox{0.8}{ \centerline{\xymatrix@R=5pt{ 112\ar@{-} '[4,0]+0 `d[5,1] [5,1]&&4\ar@{-} '[2,0]+0 `d[3,1] [3,1]&& 25\ar@{-} `d[1,1] [1,1]&&17\ar@{-} `d[1,-1] [1,-1]&&48\ar@{-} '[6,0]+0 `d[7,- 1] [7,-1]& \\ &&&&&*+[o][F]{-}\ar@{-}[d]&&&& \\ &&&&&*+{8}\ar@{-} `d[1,-2] [1,-2]&&&& \\ &&&*+[o][F]{\txt{$\cdot$}}\ar@{-}[d]&&&&&& \\ &&&*+{32}\ar@{-} `d[1,-2] [1,-2]&&&&&& \\ &*+[o][F]{-}\ar@{-}[d]&&&&&&&& \\ &*+{80}\ar@{-} `d[1,6] [1,6]&&&&&&&& \\ &&&&&&&*+[o][F]{+}\ar@{-}[d]&& \\ &&&&&&&*+{128}&& } } }

Programm

Hier kommt das awk-Skript:

 rechenbaum.awk 
function tilt() { printf("Falsch geklammerte Formel!\n") > "/dev/stderr"; exit; } function atom(formel) { return(!match(formel,"[\\(\\)]")); } function left(formel, res,depth,pos) { if (!match(formel,"^\\(.*\\)$")) tilt(); res=substr(formel,2,length(formel)-2); depth=0; pos=1; while (!((depth==0) && (match(substr(res,pos,1),"[\\-\\+\\*:]")))) { if (substr(res,pos,1)=="(") depth++; if (substr(res,pos,1)==")") depth--; if ((depth<0) || (pos>length(res))) tilt(); pos++; } return substr(res,1,pos-1); } function op(formel) { return substr(formel,length(left(formel))+2,1); } function right(formel) { return substr(formel,length(left(formel))+3, length(formel)-length(left(formel))-3); } function depth(formel, dl,dr) { if (atom(formel)) return 0; dl=depth(left(formel)); dr=depth(right(formel)); return (dl1) res=res sprintf(" '[%i,0]+0",dy-1); res=res sprintf(" `d[%i,%i] [%i,%i]",dy,dx,dy,dx); return res; } function layout(formel,x, froml,fromr,mid,y,dx,dy) { y=depth(formel); if (atom(formel)) { grid[x,0]=formel; return x; } else { mid=x+width(left(formel)); froml=layout(left(formel),x); fromr=layout(right(formel),x+width(left(formel))+1); grid[mid,y*2-1]=sprintf("*+[o][F]{%s}", (op(formel)!="*")?op(formel):"\\txt{$\\cdot$}"); grid[mid,y*2]=sprintf("*+%s{%s}",(solve)?"":"[F]",(solve)?eval(formel): "\\makebox(30,10){}"); grid[froml,depth(left(formel))*2]=grid[froml,depth(left(formel))*2] arrow( mid-froml,2*(depth(formel)-depth(left(formel)))-1); grid[fromr,depth(right(formel))*2]=grid[fromr,depth(right(formel))*2] arrow( mid-fromr,2*(depth(formel)-depth(right(formel)))-1); grid[mid,2*y-1]=grid[mid,2*y-1]sprintf("\\ar@{-}[d]"); return mid; } } BEGIN { if (!include) { printf("\\documentclass{article}\n"); printf("\\usepackage[all]{xy}\n"); printf("\\begin{document}\n"); printf("\\thispagestyle{empty}\n\n"); } } /./ { gsub(" ",""); delete grid; layout($0,0); printf("%% %s\n\n",$0); printf("\\scalebox{0.8}{ \n"); printf("\\centerline{"); printf("\\xymatrix@R=5pt{\n"); for (y=0; y<=depth($0)*2; y++) { printf(" "); len=2; for (x=0; x<=width($0); x++) { len+=length(grid[x,y]); if (len>=74) { printf("\n "); len=4; } printf("%s",grid[x,y]); if (x

Letzte Änderung: 26.04.2012: 17:24:04 von X. Rendtel

Creative Commons Lizenzvertrag
Dieses Werk bzw. Inhalt steht unter einer Creative Commons Namensnennung-Weitergabe unter gleichen Bedingungen 3.0 Unported Lizenz.
Beruht auf einem Inhalt unter www.rendtel.de.