Aus reinem Interesse an dem Thema habe ich mal ein Programm zum differnzieren von Funktionen geschrieben (ich weiß das gibt es schon). Funktioniert vom Grundprinzip auch ganz gut. Allerdings ist es mir dann doch zu viel Arbeit das weiter zu machen und sowas wie die e-Funktion, die restlichen trigonometrischen Funktionen, auf einen Hauptnenner bringen usw. einzubauen. Aber vielleicht interessiert es ja jemanden, also poste ich den aktuellen Status mal hier (hoffe das ist dafür der richtige Bereich). Viel Spaß

Code: Alles auswählen
Enumeration 1 ; Gadgets durchnummerieren
#C_Input ; Eingabeschaltflächen
#T_Input ; Überschrift Eingabe
#E_Input ; Eingabe der Funktion die abgeleitet werden soll
#C_ILatex ; Input in Latex-Schreibweise darstellen
#C_Output ; Ausgabeschaltflächen
#T_Output ; Überschrift Ausgabe
#E_Output ; Ausgabe der Funktion die abgeleitet wurde
#C_OLatex ; Output in Latex-Schreibweise darstellen
#S_Splitter
#B_Deriv
EndEnumeration
Enumeration 1 ; Operatoren
#Value ; Objekt ist Wert
#Var ; Objekt ist Variable
#X ; Objekt ist X
#Add ; a '+' b (a, b sind Objekte)
#Subtract ; a '-' b
#Multiply ; a '*' b
#Divide ; a '/' b
#Power ; a '^' b
#EPower ; 'e^' a
#Sin ; 'sin' a
#Cos ; 'cos' a
#Tan ; 'tan' a
#ASin ; 'asin' a
#ACos ; 'acos' a
#ATan ; 'atan' a
#Cot ; 'cot' a
#Ln ; 'ln' a (logarithmus naturalis)
; #Quad ; a '²'
; #Cubic ; a '³'
EndEnumeration
Structure MObj ; Rechenobjekte
*Parent.mobj ; Objekt, dass das Objekt beinhaltet
Type.l ; Welcher Operator / Typ
*Child.MObj [2] ; Bis jetzt maximal 2 Objekte
EndStructure
Macro SetObjectText(Object, Text)
PokeS(Object + SizeOf(MObj), Text) ; Wert im Objekt speichern
EndMacro
Macro GetObjectText(Object)
PeekS(Object + SizeOf(MObj)) ; Wert aus dem Objekt holen
EndMacro
;*************************************************************************************************************
;*************************************************************************************************************
Procedure CreateMObj(*Parent.MObj=0, Index=0, Size=0) ; Mathe-Objekt erzeugen
If Size > 0 ; Zusätzlicher Anhang
*Obj.MObj = AllocateMemory(SizeOf(MObj)+Size+1) ; Speicher dafür erzeugen (Textzeile)
Else
*Obj.MObj = AllocateMemory(SizeOf(MObj)) ; Speicher dafür erzeugen (Nur Objektdaten)
EndIf
If *Obj And *Parent ; Wenn das geklappt hat und ein Elternobjekt angegeben ist
*Obj\Parent = *Parent ; Elternobjekt angeben
*Parent\Child[Index] = *Obj ; Objekt eintragen
EndIf
ProcedureReturn *Obj ; Objekt zurückgeben
EndProcedure
;*************************************************************************************************************
Procedure DestroyMObj(*MObj.MObj) ; Mathe-Objekt entfernen
For i=0 To 1 ; Parameter durchgehen
If *MObj\Child [i] ; Wenn es ein Unterobjekt gibt ...
DestroyMObj(*MObj\Child [i]) ; Unterobjekt ebenfalls freigeben
EndIf
If *MObj\Parent And *MObj\Parent\Child [i] = *MObj ; Wenn das Child vom Parent i gerade dieses hier ist ...
*MObj\Parent\Child [i] = 0 ; Child i existiert nicht mehr
EndIf
Next
FreeMemory(*MObj) ; Speicherbereich des Objekts freigeben
ProcedureReturn 0 ; Erfolgreich
EndProcedure
;*************************************************************************************************************
Procedure CopyMObj(*Old.MObj, *Parent.MObj, Index=0) ; Objekt kopieren
*New.MObj = AllocateMemory(MemorySize(*Old)) ; Neuen Speicherbereich mit selber Dimension
CopyMemory(*Old, *New, MemorySize(*Old)) ; Alte Daten kopieren
*New\Parent = *Parent ; Parent ändern
If *New\Parent ; Wenn es ein Vaterobjekt gibt ...
*New\Parent\Child [Index] = *New ; Child Index eintragen ...
EndIf
For i=0 To 1 ; Parameter durchgehen
If *Old\Child[i] <> 0 ; Objekt i ist da -> ...
CopyMObj(*Old\Child[i], *New, i) ; Auch dieses kopieren
EndIf
Next
ProcedureReturn *New
EndProcedure
;*************************************************************************************************************
Procedure ResizeMObj(*MObj.MObj, Size=0) ; Objektgröße ändern (um z.B. den Typ zu ändern)
*New.MObj = ReAllocateMemory(*MObj, SizeOf(MObj)+Size+1) ; Speicherbereich ändern
If *New ; Wenn das geklappt hat
For i=0 To 1 ; Alle Parameter durchgehen
If *New\Parent And *New\Parent\Child [i] = *MObj ; Wenn das Child i des Parents die alte Addresse ist ...
*New\Parent\Child [i] = *New ; Neue Addresse eintragen
EndIf
If *New\Child [i] ; Wenn es ein Child gibt
*New\Child[i]\Parent = *New ; Vater auf neue Addresse ändern
EndIf
Next
EndIf
ProcedureReturn *New ; Neue Addresse zurückgeben
EndProcedure
;*************************************************************************************************************
Procedure ReplaceMObj(*Old.MObj, *New.MObj) ; Objekt einfügen (löscht altes nicht)
If *Old\Parent ; Wenn es ein Elternobjekt gibt
If *Old\Parent\Child[0] = *Old ; Wenn das Child das aktuelle ist
*Old\Parent\Child[0] = *New
ElseIf *Old\Parent\Child[1] = *Old ; Wenn das Child das aktuelle ist
*Old\Parent\Child[1] = *New
EndIf
EndIf
*New\Parent = *Old\Parent
ProcedureReturn *New ; Neues einfügen
EndProcedure
;*************************************************************************************************************
;*************************************************************************************************************
Procedure.s OperatorName(Operator.l) ; Namen des Operators ermitteln
Protected Name$ = ""
Select Operator
Case #Add : Name$ = "+" ; a '+' b (a, b sind Objekte)
Case #Subtract : Name$ = "-" ; a '-' b
Case #Multiply : Name$ = "*" ; a '*' b
Case #Divide : Name$ = "/" ; a '/' b
Case #EPower : Name$ = "e^" ; 'e^' a
Case #Power : Name$ = "^" ; a '^' b
Case #Sin : Name$ = "sin" ; 'sin' a
Case #Cos : Name$ = "cos" ; 'cos' a
Case #Tan : Name$ = "tan" ; 'tan' a
Case #ASin : Name$ = "asin" ; 'asin' a
Case #ACos : Name$ = "acos" ; 'acos' a
Case #ATan : Name$ = "atan" ; 'atan' a
Case #Cot : Name$ = "cot" ; 'cot' a
Case #X : Name$ = "x" ; 'x'
EndSelect
ProcedureReturn Name$
EndProcedure
;*************************************************************************************************************
Procedure OpenMainWindow(W=400, H=300) ; Hauptfenster öffnen
OpenWindow(0, 0, 0, W, H, "Ableiter", #PB_Window_ScreenCentered | #PB_Window_Invisible | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
CreateGadgetList(WindowID(0))
ContainerGadget (#C_Input, 0, 0, W-10, 60)
TextGadget (#T_Input, 0, 0, 60, 15, "Funktion:")
CheckBoxGadget(#C_ILatex, 65, 0, 70, 15, "Latexcode")
EditorGadget (#E_Input, 0, 20, W-10, 100)
CloseGadgetList()
ContainerGadget (#C_Output, 0, 0, W-10, 60)
TextGadget (#T_Output, 0, 5, 60, 15, "Ableitung:")
CheckBoxGadget(#C_OLatex, 65, 5, 70, 15, "Latexcode")
EditorGadget (#E_Output, 0, 25, W-10, 100, #PB_Editor_ReadOnly)
CloseGadgetList()
SplitterGadget (#S_Splitter, 5, 5, W-10, H-35, #C_Input, #C_Output, #PB_Splitter_Separator) ; Größen Veränderbar
SetGadgetState (#S_Splitter, (H-35)/2)
ButtonGadget (#B_Deriv, 5, H-25, 100, 20, "Ableiten")
HideWindow(0, 0) ; Fenster anzeigen
EndProcedure
;*************************************************************************************************************
Procedure ResizeGadgets(Mode.l)
W = WindowWidth(0)
H = WindowHeight(0)
If Mode
If W < 150 ; Minimalbreite
ResizeWindow(0, #PB_Ignore, #PB_Ignore, 150, #PB_Ignore)
EndIf
If H < 90 ; Minimalhöhe
ResizeWindow(0, #PB_Ignore, #PB_Ignore, #PB_Ignore, 90)
EndIf
ResizeGadget(#S_Splitter, 5, 5, W-10, H-35)
ResizeGadget(#B_Deriv, 5, H-25, 100, 20)
EndIf
ResizeGadget(#E_Input, 0, 20, W-10, GadgetHeight(#C_Input) - 25)
ResizeGadget(#E_Output, 0, 25, W-10, GadgetHeight(#C_Output) - 30)
;HideGadget(#C_Input, 1)
;HideGadget(#C_Output, 1)
EndProcedure
;*************************************************************************************************************
Procedure Simplyfy(*MObj.MObj) ; Objekt vereinfachen
Debug "*MObj: ---------------"
Debug "Parent = " + Str(*MObj\Parent)
Debug "Type = " + Str(*MObj\Type )
Debug "Child[0] = " + Str(*MObj\Child[0])
Debug "Child[1] = " + Str(*MObj\Child[1])
Select *MObj\Type ; Typ ermitteln
Case #Add, #Subtract
Simplyfy(*MObj\Child[0]) ; Erstes Objekt vereinfachen
Simplyfy(*MObj\Child[1]) ; Zweites Objekt vereinfachen
If *MObj\Child[0]\Type = #Value And GetObjectText(*MObj\Child[0]) = "0" ; A+0 = A, A-0 = A
*Old.MObj = *MObj ; Addresse speichern
*MObj = ReplaceMObj(*Old, *Old\Child[1]) ; Aktuelles mit dem darin ersetzen
*Old\Child[1] = 0 ; Objekt ist nicht mehr zur Verfügung
DestroyMObj(*Old) ; Die alte Summe mit der 0 entfernen
ElseIf *MObj\Child[1]\Type = #Value And GetObjectText(*MObj\Child[1]) = "0" ; A+0 = A, A-0 = A
*Old.MObj = *MObj ; Addresse speichern
*MObj = ReplaceMObj(*Old, *Old\Child[0]) ; Aktuelles mit dem darin ersetzen
*Old\Child[0] = 0 ; Objekt ist nicht mehr zur Verfügung
DestroyMObj(*Old) ; Die alte Summe mit der 0 entfernen
EndIf
Case #Multiply
Simplyfy(*MObj\Child[0]) ; Erstes Objekt vereinfachen
Simplyfy(*MObj\Child[1]) ; Zweites Objekt vereinfachen
If *MObj\Child[0]\Type = #Value And GetObjectText(*MObj\Child[0]) = "1" ; 1*A = A
*Old.MObj = *MObj ; Addresse speichern
*MObj = ReplaceMObj(*Old, *Old\Child[1]) ; Aktuelles mit dem darin ersetzen
*Old\Child[1] = 0 ; Objekt ist nicht mehr zur Verfügung
DestroyMObj(*Old) ; Das alte Produkt mit der 1 entfernen
ElseIf *MObj\Child[1]\Type = #Value And GetObjectText(*MObj\Child[1]) = "1" ; A*1 = A
*Old.MObj = *MObj ; Addresse speichern
*MObj = ReplaceMObj(*Old, *Old\Child[0]) ; Aktuelles mit dem darin ersetzen
*Old\Child[0] = 0 ; Objekt ist nicht mehr zur Verfügung
DestroyMObj(*Old) ; Das alte Produkt mit der 1 entfernen
Else
If *MObj\Child[0]\Type = #Value And GetObjectText(*MObj\Child[0]) = "0" ; 0*A = 0
*Old.MObj = *MObj ; Addresse speichern
*MObj = ReplaceMObj(*Old, *Old\Child[0]) ; Aktuelles mit dem darin ersetzen
*Old\Child[0] = 0 ; Objekt ist nicht mehr zur Verfügung
DestroyMObj(*Old) ; Das alte Produkt mit dem A entfernen
ElseIf *MObj\Child[1]\Type = #Value And GetObjectText(*MObj\Child[1]) = "0" ; A*0 = 0
*Old.MObj = *MObj ; Addresse speichern
*MObj = ReplaceMObj(*Old, *Old\Child[1]) ; Aktuelles mit dem darin ersetzen
*Old\Child[1] = 0 ; Objekt ist nicht mehr zur Verfügung
DestroyMObj(*Old) ; Das alte Produkt mit der A entfernen
EndIf
EndIf
Case #Divide
Simplyfy(*MObj\Child[0]) ; Erstes Objekt vereinfachen
Simplyfy(*MObj\Child[1]) ; Zweites Objekt vereinfachen
If *MObj\Child[1]\Type = #Value And GetObjectText(*MObj\Child[1]) = "1" ; A/1
*Old.MObj = *MObj ; Addresse speichern
*MObj = ReplaceMObj(*Old, *Old\Child[0]) ; Aktuelles mit dem darin ersetzen
*Old\Child[0] = 0 ; Objekt ist nicht mehr zur Verfügung
DestroyMObj(*Old) ; Den alten Quotienten mit der 1 entfernen
EndIf
EndSelect
ProcedureReturn *MObj
EndProcedure
;*************************************************************************************************************
Procedure BWith(Text$, Pos, Find$, Wordproof=0) ; Begins with
If UCase(Find$) = UCase( Mid(Text$, Pos, Len(Find$)) ) ; Gefunden
If Wordproof = 1
If Pos > 1 : A = PeekC(@Text$+Pos-2) : EndIf ; Vorheriges Zeichen
If Pos < Len(Text$)-1 : B = PeekC(@Text$+Pos+Len(Find$)-1) : EndIf ; Nächstes Zeichen
If ( B => 'a' And B <= 'z' ) Or ( B => 'A' And B <= 'Z' ) Or ( A => 'a' And B <= 'z' ) Or ( A => 'A' And B <= 'Z' ) ; Wenn drumherrum ein Buchstabe ...
ProcedureReturn 0 ; Trotzdem nicht richtig
Else ; Sonst ...
ProcedureReturn 1 ; richtig
EndIf
Else
ProcedureReturn 1 ; richtig
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
;*************************************************************************************************************
Procedure FindBracketEnd(Text$, Pos, Open$, Close$)
NextOpen = Pos
NextClose = Pos
; ( (a( b(( ))b )a) )
Repeat
NextOpen = FindString(Text$, Open$, NextOpen +1)
NextClose = FindString(Text$, Close$, NextClose+1)
Until NextOpen > NextClose Or NextOpen = 0
If NextClose = 0
NextClose = Len(Text$)+1
EndIf
ProcedureReturn NextClose
EndProcedure
Procedure FindEnd(Text$, Pos) ; Endposition finden
For X=Pos To Len(Text$)
Char$ = Mid(Text$, X, 1) ; Aktuelles Zeichen
If Char$ = "(" ; Eine der 'Klammer auf'
X = FindBracketEnd(Text$, X, "(",")") ; Klammer zu finden
Break
ElseIf Char$ = " " Or Char$ = #TAB$ ; Nichts
If NoSpace ; Wenn es keine führenden Leerzeichen sind
X-1 ; Das gehört schon nicht mehr dazu
Break
EndIf
Else
NoSpace = 1 ; Ausnahmsweise mal kein Leerzeichen
EndIf
Next
ProcedureReturn X ; Position zurückgeben
EndProcedure
;*************************************************************************************************************
Procedure.s ObjectToText(*MObj.MObj) ; Objekt in Text umwandeln
Op$ = OperatorName(*MObj\Type) ;
Debug "["+Op$+"]"
Select *MObj\Type ; Art des Objekts ermitteln
Case #Add To #Divide ; 2-Stufige Operation
T$ = "(" + ObjectToText(*MObj\Child[0]) + " " + Op$ + " " + ObjectToText(*MObj\Child[1]) + ")"
Case #X
T$ = "x" ; X
Case #Sin To #Cos ; 1-Stellige Operatoren
T$ = Op$ + "(" + ObjectToText(*MObj\Child[0]) + ")"
Case #Value, #Var ; Direkte Werte
T$ = GetObjectText(*MObj) ; Text ermitteln
EndSelect
Debug T$
ProcedureReturn T$ ; Text zurückgeben
EndProcedure
;*************************************************************************************************************
Procedure TextToObject(Text$, *Parent.MObj=0, Index=0) ; Text in Objekt umwandeln
Text$ = Trim(Text$) ; Überschüssige Leerzeichen weglassen
While Left(Text$, 1) = "(" ; Außenklammern entfernen
BracketEnd = FindBracketEnd(Text$, 1, "(",")")
If BracketEnd => Len(Text$) ; Nur wenn Klammer um alles ist
Text$ = Trim(Mid(Text$, 2, BracketEnd-2)) ; Die Klammer entfernen
Else
Break ; Abbrechen, da fertig
EndIf
Wend
For Op=#Add To #Divide ; echte 2-Seitige Operatoren
Op$ = OperatorName(Op) ; Namen ermitteln
For X = 1 To Len(Text$) ; Text durchgehen
Char$ = Mid(Text$, X, 1) ; Aktuelles Zeichen
If Char$ = "(" ; Eine der 'Klammer auf'
X = FindBracketEnd(Text$, X, "(",")") + 1 ; Klammer zu finden und danach weitermachen
EndIf
If BWith(Text$, X, Op$) ; Wenn der Operator gefunden wurde
*Actual.MObj = CreateMObj(*Parent, Index) ; Objekt hinzufügen
Debug "Objekt Erstellen: -------------------------"
Debug "Operator = " + Op$
Debug "Parameter 1 = " + Left(Text$, X-1)
Debug "Parameter 2 = " + Mid (Text$, X+Len(Op$))
*Actual\Type = Op ; Operator eintragen
TextToObject(Left(Text$, X-1), *Actual, 0) ; Alles davor ist erster Parameter
TextToObject(Mid (Text$, X+Len(Op$)), *Actual, 1) ; Alles danach ist zweiter Parameter
ProcedureReturn *Actual ; Fertig
EndIf
Next
Next
For Op=#Sin To #Cos
Op$ = OperatorName(Op) ; Namen ermitteln
For X = 1 To Len(Text$) ; Text durchgehen
Char$ = Mid(Text$, X, 1) ; Aktuelles Zeichen
If Char$ = "(" ; Eine der 'Klammer auf'
X = FindBracketEnd(Text$, X, "(",")")+1 ; Klammer zu finden
EndIf
If BWith(Text$, X, Op$, 1) ; Wenn der Operator gefunden wurde
*Actual.MObj = CreateMObj(*Parent, Index) ; Objekt hinzufügen
Debug "Objekt Erstellen: -------------------------"
Debug "Operator = " + Op$
Debug "Parameter = " + Mid (Text$, X+Len(Op$))
*Actual\Type = Op ; Operator speichern
TextToObject(Mid (Text$, X+Len(Op$)), *Actual, 0) ; Alles danach ist Parameter
ProcedureReturn *Actual ; Fertig
EndIf
Next
Next
Debug "Objekt Erstellen: -------------------------"
Debug "Wert = [ " + Text$ + " ]"
*Actual.MObj = CreateMObj(*Parent, Index, Len(Text$)) ; Objekt erzeugen
SetObjectText(*Actual, Text$) ; Text abspeichern
If Asc(Text$) => '0' And Asc(Text$) <= '9'
*Actual\Type = #Value ; Zahl (z.B.: 105948.0144)
ElseIf UCase(Text$) = "X"
*Actual\Type = #X ; X
Else
*Actual\Type = #Var ; Variable
EndIf
ProcedureReturn *Actual ; Fertig
ProcedureReturn 0 ; Fehlgeschlagen
EndProcedure
;*************************************************************************************************************
Procedure Diff(*MObj.MObj, *Parent.MObj=0, Index=0) ; Objekt ableiten
Select *MObj\Type ; Verschieden ableiten
; Summenregel: (f + g)' = f' + g' ************************************************************************
Case #Add ; Addieren zweier Objekte
*Diffed.MObj = CreateMObj(*Parent, Index) ; Neues Erzeugen
Diff (*MObj\Child[0], *Diffed, 0) ; f'
*Diffed\Type = #Add ; +
Diff (*MObj\Child[1], *Diffed, 1) ; g'
Debug "+"
; Summenregel: (f - g)' = f' - g' ************************************************************************
Case #Subtract ; Subtrahieren zweier Objekte
*Diffed.MObj = CreateMObj(*Parent, Index) ; Neues Erzeugen
Diff (*MObj\Child[0], *Diffed, 0) ; f'
*Diffed\Type = #Subtract ; -
Diff (*MObj\Child[1], *Diffed, 1) ; g'
Debug "-"
; Produktregel: (f * g)' = (f' * g) + (f * g') ***********************************************************
Case #Multiply ; Multiplizieren zweier Objekte
*Diffed.MObj = CreateMObj(*Parent, Index) ; Neues Erzeugen
*D_0.MObj = CreateMObj(*Diffed, 0)
Diff (*MObj\Child[0], *D_0, 0) ; ( f'
*D_0\Type = #Multiply ; *
CopyMObj(*MObj\Child[1], *D_0, 1) ; g )
*Diffed\Type = #Add ; +
*D_1.MObj = CreateMObj(*Diffed, 1)
CopyMObj(*MObj\Child[0], *D_1, 0) ; ( f
*D_1\Type = #Multiply ; *
Diff (*MObj\Child[1], *D_1, 1) ; g' )
Debug "*"
; Quotientenregel: (g / h)' = ((g' * h) - (g * h')) / (h*h) **********************************************
Case #Divide ; Dividieren zweier Objekte
*Diffed.MObj = CreateMObj(*Parent, Index) ; Neues Erzeugen
*D_0.MObj = CreateMObj(*Diffed, 0)
*D_00.MObj = CreateMObj(*D_0, 0)
Diff (*MObj\Child[0], *D_00, 0) ; ( g'
*D_00\Type = #Multiply ; *
CopyMObj(*MObj\Child[1], *D_00, 1) ; h )
*D_0\Type = #Subtract ; -
*D_01.MObj = CreateMObj(*D_0, 1)
CopyMObj(*MObj\Child[0], *D_01, 0) ; ( g
*D_01\Type = #Multiply ; *
Diff (*MObj\Child[1], *D_01, 1) ; h' )
*Diffed\Type = #Divide ; ----------------------------------
*D_1.MObj = CreateMObj(*Diffed, 1)
CopyMObj(*MObj\Child[1], *D_1, 0) ; ( h
*D_1\Type = #Multiply ; *
CopyMObj(*MObj\Child[1], *D_1, 1) ; h )
Debug "/"
; Sinus, Kettenregel: (sin h)' = (cos h) * h' ************************************************************
Case #Sin ; Sinus berechnen
*Diffed.MObj = CreateMObj(*Parent, Index) ; Neues Erzeugen
*D_0.MObj = CreateMObj(*Diffed, 0)
*D_0\Type = #Cos ; ( Cos
CopyMObj(*MObj\Child[0], *D_0, 0) ; h )
*Diffed\Type = #Multiply ; *
Diff (*MObj\Child[0], *Diffed, 1) ; h'
Debug "Sin"
; Cosinus, Kettenregel: (cos h)' = ( (-1 * (sin h)) * h') ************************************************
Case #Cos ; Cosinus berechnen
*Diffed.MObj = CreateMObj(*Parent, Index) ; Neues Erzeugen
*D_0.MObj = CreateMObj(*Diffed, 0)
*D_00.MObj = CreateMObj(*D_0, 0, 2)
*D_00\Type = #Value
SetObjectText(*D_00, "-1") ; -1
*D_0\Type = #Multiply ; *
*D_01.MObj = CreateMObj(*D_0, 1)
*D_01\Type = #Sin ; ( Sin
CopyMObj(*MObj\Child[0], *D_01, 0) ; h )
*Diffed\Type = #Multiply ; *
Diff (*MObj\Child[0], *Diffed, 1) ; h'
Debug "Cos"
; Konstante Funktion: (a)' = 0 ***************************************************************************
Case #Var, #Value ; Wert oder Variable
*Diffed.MObj = CreateMObj(*Parent, Index, 1) ; Neues Erzeugen
*Diffed\Type = #Value ;
SetObjectText(*Diffed, "0") ; 0
Debug "1, a"
; Einzige Funktion die er ableiten kann: x' = 1 **********************************************************
Case #X ; X
*Diffed.MObj = CreateMObj(*Parent, Index, 1) ; Neues Erzeugen
*Diffed\Type = #Value ;
SetObjectText(*Diffed, "1") ; 1
Debug "X"
EndSelect
ProcedureReturn *Diffed
EndProcedure
;*************************************************************************************************************
;*************************************************************************************************************
OpenMainWindow()
Repeat
WEvent = WaitWindowEvent()
If WEvent = #PB_Event_SizeWindow
ResizeGadgets(1)
ElseIf WEvent = #PB_Event_Gadget
Select EventGadget()
Case #S_Splitter : ResizeGadgets(0)
Case #B_Deriv : *Object.MObj = TextToObject(GetGadgetText(#E_Input))
If *Object
*Diffed.MObj = Diff(*Object)
*Diffed = Simplyfy(*Diffed)
SetGadgetText(#E_Output, ObjectToText(*Diffed) )
DestroyMObj(*Object)
DestroyMObj(*Diffed)
EndIf
EndSelect
EndIf
Until WEvent = #PB_Event_CloseWindow
End