Files
s4-ap-fp/wk5/src/Modelling2.elm
2024-03-22 23:30:36 +01:00

134 lines
3.9 KiB
Elm

module Modelling2 exposing (..)
import Modelling1 exposing (..)
import HighOrder exposing (..)
{-
Modelling Math Functions (part 2)
Dimitar Byalkov and Kaloyan Stoykov
-}
f: Function
f = Plus (Mult (Plus (Const 3) X) (Minus X (Poly X 5))) (Const 2)
derivative: Function -> Function
derivative func =
case func of
-- constant
Const _ ->
Const 0
-- X
X ->
Const 1
-- sum
Plus left right ->
Plus (derivative left) (derivative right)
-- difference
Minus left right ->
Minus (derivative left) (derivative right)
-- product
Mult left right ->
Plus (Mult (derivative left) right) (Mult left (derivative right))
-- quotient
Div left right ->
Div (Minus (Mult (derivative left) right) (Mult left (derivative right)))
(Poly right 2)
-- power
Poly X right ->
Mult (Const right) (Poly X (right - 1))
Poly left right ->
Poly (derivative left) right
simplify: Function -> Function
simplify func =
-- tries to simplify until no further simplification is possible
repeatUntil (\x -> x == simplifyHelp x) simplifyHelp func
simplifyHelp: Function -> Function
simplifyHelp func =
case func of
-- arithmetics
Mult (Const left) (Const right) ->
Const (left * right)
Div (Const left) (Const right) ->
Const (left // right)
Plus (Const left) (Const right) ->
Const (left + right)
Minus (Const left) (Const right) ->
Const (left - right)
-- nested addition and subtraction
Poly left 1 ->
left
Poly _ 0 ->
(Const 1)
Poly (Const left) right ->
Const (left ^ right)
Poly left right ->
Poly left right
Mult (Const 1) right ->
right
Mult left (Const 1) ->
left
Mult _ (Const 0) ->
(Const 0)
Div (Const 0) _ ->
(Const 0)
Div left (Const 1) ->
left
Plus left (Const 0) ->
left
Plus (Const 0) right ->
right
Minus left (Const 0) ->
left
-- recursive simplification
Mult left right ->
Mult (simplify left) (simplify right)
Div left right ->
Div (simplify left) (simplify right)
Plus left right ->
Plus (simplify left) (simplify right)
Minus left right ->
Minus (simplify left) (simplify right)
_ ->
func
-- Tests
testPrintFunc: Bool
testPrintFunc = print f == "(((3+x)*(x-(x^5)))+2)"
testPrintDerivFunc: Bool
testPrintDerivFunc = print (derivative f) ==
"((((0+1)*(x-(x^5)))+((3+x)*(1-(5*(x^4)))))+0)"
testPrintSimplifyDerivFunc: Bool
testPrintSimplifyDerivFunc = print (simplify (derivative f)) ==
"((x-(x^5))+((3+x)*(1-(5*(x^4)))))"
testDerivX: Bool
testDerivX = derivative X == Const 1
testDerivConst: Bool
testDerivConst = derivative (Const 5) == Const 0
testDerivPlus: Bool
testDerivPlus = derivative (Plus X (Const 9)) == Plus (Const 1) (Const 0)
testDerivMult: Bool
testDerivMult = derivative (Mult (Const 4) X) ==
Plus (Mult (Const 0) X) (Mult (Const 4) (Const 1))
testDerivPolyX: Bool
testDerivPolyX = derivative (Poly X 3) == Mult (Const 3) (Poly X 2)
testDerivPoly: Bool
testDerivPoly = derivative (Poly (Const 4) 3) == (Poly (Const 0) 3)
testSimplePoly: Bool
testSimplePoly = simplify (Poly (Const 0) 3) == Const 0
testSimpleRecursivePlus: Bool
testSimpleRecursivePlus = simplify (Plus ((Mult (Const 1) X)) (Minus X (Const 0))) == (Plus X X)
allModelling2Tests: List Bool
allModelling2Tests = [testPrintFunc, testPrintDerivFunc, testPrintSimplifyDerivFunc, testDerivX, testDerivConst, testDerivPlus, testDerivMult, testDerivPolyX, testDerivPoly, testSimplePoly, testSimpleRecursivePlus]