Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Partial eval #1077

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
4 changes: 2 additions & 2 deletions cli/src/Morphir/Elm/CLI.elm
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import Morphir.IR.Type exposing (Type)
import Morphir.IR.Value as Value
import Morphir.SDK.ResultList as ResultList
import Morphir.Type.Infer as Infer
import Morphir.Value.Interpreter exposing (evaluateFunctionValue)
import Morphir.Value.Interpreter exposing (complete, evaluateFunctionValue)


port packageDefinitionFromSource : (( Decode.Value, Decode.Value, List SourceFile ) -> msg) -> Sub msg
Expand Down Expand Up @@ -217,7 +217,7 @@ update msg model =
testCaseList
|> List.map
(\testCase ->
case evaluateFunctionValue SDK.nativeFunctions ir functionName testCase.inputs of
case evaluateFunctionValue complete SDK.nativeFunctions ir functionName testCase.inputs of
Ok rawValue ->
if rawValue == testCase.expectedOutput then
( "PASS"
Expand Down
4 changes: 2 additions & 2 deletions cli/src/Morphir/Web/DevelopApp.elm
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import Morphir.SDK.Dict as SDKDict
import Morphir.TestCoverage.Backend exposing (getBranchCoverage, getValueBranchCoverage)
import Morphir.Type.Infer as Infer
import Morphir.Value.Error exposing (Error)
import Morphir.Value.Interpreter exposing (evaluateFunctionValue)
import Morphir.Value.Interpreter exposing (complete, evaluateFunctionValue)
import Morphir.Visual.Common exposing (nameToText, nameToTitleText, pathToDisplayString, pathToFullUrl, pathToTitleText, pathToUrl, tooltip)
import Morphir.Visual.Components.Card as Card
import Morphir.Visual.Components.FieldList as FieldList
Expand Down Expand Up @@ -2218,7 +2218,7 @@ viewDefinitionDetails model =

evaluateOutput : Distribution -> List (Maybe RawValue) -> FQName -> Result Error RawValue
evaluateOutput ir inputs fQName =
evaluateFunctionValue SDK.nativeFunctions ir fQName inputs
evaluateFunctionValue complete SDK.nativeFunctions ir fQName inputs

viewRawValue : Morphir.Visual.Config.Config Msg -> Distribution -> RawValue -> Element Msg
viewRawValue config ir rawValue =
Expand Down
3 changes: 2 additions & 1 deletion morphir.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"IR.Value",
"IR.Module",
"IR.Package",
"IR.Distribution"
"IR.Distribution",
"Value.Interpreter"
]
}
4 changes: 2 additions & 2 deletions src/Morphir/Correctness/BranchCoverage.elm
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ assignTestCasesToBranches ir valueDef testCases =
rawCriterion =
cond.criterion |> Value.mapValueAttributes (always ()) (always ())
in
case Interpreter.evaluateValue SDK.nativeFunctions ir variables [] rawCriterion of
case Interpreter.evaluateValue Interpreter.complete SDK.nativeFunctions ir variables [] rawCriterion of
Ok (Value.Literal _ (BoolLiteral actualResult)) ->
if cond.expectedValue == actualResult then
matchesConditions restOfConditions
Expand All @@ -324,7 +324,7 @@ assignTestCasesToBranches ir valueDef testCases =

evaluatedSubject : RawValue
evaluatedSubject =
case Interpreter.evaluateValue SDK.nativeFunctions ir variables [] rawSubject of
case Interpreter.evaluateValue Interpreter.complete SDK.nativeFunctions ir variables [] rawSubject of
Ok result ->
result

Expand Down
353 changes: 275 additions & 78 deletions src/Morphir/Value/Interpreter.elm

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/Morphir/Value/Native.elm
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,9 @@ encodeLocalDate localDate =

{-| -}
decodeLocalDate : Decoder LocalDate
decodeLocalDate _ value =
case value of
Value.Apply () (Value.Reference () ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "local", "date" ] ], [ "from", "i", "s", "o" ] )) (Value.Literal () (StringLiteral str)) ->
decodeLocalDate eval value =
case eval value of
Ok (Value.Apply () (Value.Constructor () ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "maybe" ] ], [ "just" ] )) (Value.Apply () (Value.Reference () ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "local", "date" ] ], [ "from", "i", "s", "o" ] )) (Value.Literal () (StringLiteral str)))) ->
case LocalDate.fromISO str of
Just localDate ->
Ok localDate
Expand Down
2 changes: 1 addition & 1 deletion src/Morphir/Visual/Config.elm
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fromIR ir visualState eventHandlers =

evaluate : RawValue -> Config msg -> Result String RawValue
evaluate value config =
Interpreter.evaluateValue config.nativeFunctions config.ir config.state.variables [] value
Interpreter.evaluateValue Interpreter.complete config.nativeFunctions config.ir config.state.variables [] value
|> Result.mapError
(\error ->
error
Expand Down
2 changes: 1 addition & 1 deletion src/Morphir/Visual/ViewApply.elm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Morphir.IR.Type as Type exposing (Type)
import Morphir.IR.Value as Value exposing (RawValue, Value(..), toRawValue)
import Morphir.Type.Infer as Infer
import Morphir.Value.Error exposing (Error(..))
import Morphir.Value.Interpreter exposing (evaluateFunctionValue, evaluateValue)
import Morphir.Value.Interpreter exposing (complete, evaluateFunctionValue, evaluateValue)
import Morphir.Visual.Common exposing (nameToText, tooltip)
import Morphir.Visual.Components.DecisionTree as DecisionTree
import Morphir.Visual.Components.DrillDownPanel as DrillDownPanel exposing (Depth)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,17 @@ basicRecordMany =
, record = basicRecordOne
}

type alias Rec =
{ foo: Int
, bar: String
}

calcFoo: Rec -> Int
calcFoo rec =
rec.foo

res = calcFoo { foo = 2, bar = "hello" }


basicField : { foo : String } -> String
basicField rec =
Expand Down Expand Up @@ -495,3 +506,8 @@ listFoldr2 list1 list2 =
listCons : Int -> List Int -> List Int
listCons value list =
value :: list


plus2: Int -> Int
plus2 int =
(\int1 int2 int3 -> int1 + int2 + int3) 1 2 int
223 changes: 220 additions & 3 deletions tests/Morphir/Value/InterpreterTests.elm
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
module Morphir.Value.InterpreterTests exposing (..)

import Dict
import Dict exposing (Dict)
import Expect
import Morphir.IR.Distribution exposing (Distribution(..))
import Morphir.IR.FQName exposing (FQName, fqn)
import Morphir.IR.Literal exposing (Literal(..))
import Morphir.IR.Module exposing (ModuleName)
import Morphir.IR.Name as Name exposing (Name)
import Morphir.IR.Package as Package
import Morphir.IR.QName as QName exposing (QName(..))
import Morphir.IR.SDK as SDK
import Morphir.IR.Value as Value
import Morphir.Value.Interpreter exposing (evaluate)
import Morphir.IR.Value as Value exposing (RawValue, Value)
import Morphir.Value.Interpreter exposing (evaluate, evaluateValue, partial)
import Test exposing (Test, describe, test)


Expand Down Expand Up @@ -1442,3 +1443,219 @@ evaluateValueTests =
)
(Value.List () [ Value.Literal () (WholeNumberLiteral -2), Value.Literal () (WholeNumberLiteral -4), Value.Literal () (WholeNumberLiteral -6) ])
]


evaluateValuePartialTests : Test
evaluateValuePartialTests =
let
name =
Name.fromString

var =
Value.Variable () (name "var")

int1 =
Value.Literal () (WholeNumberLiteral 1)

vars : Dict Name RawValue
vars =
Dict.fromList
[ ( name "var", var )
, ( name "int1", int1 )
]

positiveCheck : String -> Value.RawValue -> Value.RawValue -> Test
positiveCheck desc input expectedOutput =
test desc
(\_ ->
evaluateValue partial SDK.nativeFunctions (Library [ [ "empty" ] ] Dict.empty Package.emptyDefinition) vars [] input
|> Expect.equal
(Ok expectedOutput)
)
in
describe "evaluateValue partial"
[ positiveCheck "(\\val1 val2 val3 -> val1 + val2 + val3) 1 2 var == 3 + var"
(Value.Apply ()
(Value.Apply ()
(Value.Apply ()
(Value.Lambda ()
(Value.AsPattern () (Value.WildcardPattern ()) [ "val", "1" ])
(Value.Lambda ()
(Value.AsPattern () (Value.WildcardPattern ()) [ "val", "2" ])
(Value.Lambda ()
(Value.AsPattern () (Value.WildcardPattern ()) [ "val", "3" ])
(Value.Apply ()
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "Basics" "add"))
(Value.Apply ()
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "Basics" "add"))
(Value.Variable () [ "val", "1" ])
)
(Value.Variable () [ "val", "2" ])
)
)
(Value.Variable () [ "val", "3" ])
)
)
)
)
(Value.Literal () (WholeNumberLiteral 1))
)
(Value.Literal () (WholeNumberLiteral 2))
)
var
)
(Value.Apply () (Value.Apply () (Value.Reference () ( [ [ "morphir" ], [ "s", "d", "k" ] ], [ [ "basics" ] ], [ "add" ] )) (Value.Literal () (WholeNumberLiteral 3))) var)
, {- Basics.always -}
positiveCheck "List.map (always 0) [1,2,var] = [0,0,0]"
(Value.Apply ()
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "List" "map"))
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "Basics" "always"))
(Value.Literal () (WholeNumberLiteral 0))
)
)
(Value.List () [ Value.Literal () (WholeNumberLiteral 1), Value.Literal () (WholeNumberLiteral 2), var ])
)
(Value.List () [ Value.Literal () (WholeNumberLiteral 0), Value.Literal () (WholeNumberLiteral 0), Value.Literal () (WholeNumberLiteral 0) ])
, positiveCheck "List.isEmpty var = List.isEmpty var"
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "List" "isEmpty"))
var
)
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "List" "isEmpty"))
var
)
, positiveCheck "List.head var = List.head var"
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "List" "head"))
var
)
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "List" "head"))
var
)
, positiveCheck "List.head [var,[\"2\"]] == Just var"
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "List" "head"))
(Value.List () [ var, Value.List () [ Value.Literal () (StringLiteral "2") ] ])
)
(Value.Apply () (Value.Constructor () (fqn "Morphir.SDK" "Maybe" "Just")) var)
, positiveCheck "List.concat [[\"1\"],[\"2\"],var] = List.concat [[\"1\"],[\"2\"],var]"
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "List" "concat"))
(Value.List () [ Value.List () [ Value.Literal () (StringLiteral "1") ], Value.List () [ Value.Literal () (StringLiteral "2") ], var ])
)
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "List" "concat"))
(Value.List () [ Value.List () [ Value.Literal () (StringLiteral "1") ], Value.List () [ Value.Literal () (StringLiteral "2") ], var ])
)

{- IfThenElse -}
, positiveCheck "if int1 == 1 then var else False = var"
(Value.IfThenElse ()
(Value.Apply ()
(Value.Apply () (Value.Reference () (fqn "Morphir.SDK" "Basics" "equal")) int1)
(Value.Literal () (WholeNumberLiteral 1))
)
var
(Value.Literal () (BoolLiteral False))
)
var
, positiveCheck "if int1 == 1 then True else if var then False else True = if var then False else True"
(Value.IfThenElse ()
(Value.Apply ()
(Value.Apply () (Value.Reference () (fqn "Morphir.SDK" "Basics" "equal")) int1)
(Value.Literal () (WholeNumberLiteral 1))
)
(Value.Literal () (BoolLiteral True))
(Value.IfThenElse () var (Value.Literal () (BoolLiteral False)) (Value.Literal () (BoolLiteral True)))
)
(Value.Literal () (BoolLiteral True))
, positiveCheck "if int1 == 2 then var else if var then False else True = if var then False else True"
(Value.IfThenElse ()
(Value.Apply ()
(Value.Apply () (Value.Reference () (fqn "Morphir.SDK" "Basics" "equal")) int1)
(Value.Literal () (WholeNumberLiteral 2))
)
var
(Value.IfThenElse () var (Value.Literal () (BoolLiteral False)) (Value.Literal () (BoolLiteral True)))
)
(Value.IfThenElse () var (Value.Literal () (BoolLiteral False)) (Value.Literal () (BoolLiteral True)))
, positiveCheck "if int1 == 2 then var else if int1 == 3 then False else True = True"
(Value.IfThenElse ()
(Value.Apply ()
(Value.Apply () (Value.Reference () (fqn "Morphir.SDK" "Basics" "equal")) int1)
(Value.Literal () (WholeNumberLiteral 2))
)
var
(Value.IfThenElse ()
(Value.Apply ()
(Value.Apply () (Value.Reference () (fqn "Morphir.SDK" "Basics" "equal")) int1)
(Value.Literal () (WholeNumberLiteral 3))
)
(Value.Literal () (BoolLiteral False))
(Value.Literal () (BoolLiteral True))
)
)
(Value.Literal () (BoolLiteral True))
, {- Value.PatternMatch -}
positiveCheck "case var of \"Foo\" -> int1 == 1 \"Bar\" -> False = case var of \"Foo\" -> True _ -> False"
(Value.PatternMatch ()
var
[ ( Value.LiteralPattern () (StringLiteral "Foo")
, Value.Apply () (Value.Apply () (Value.Reference () (fqn "Morphir.SDK" "Basics" "equal")) int1) (Value.Literal () (WholeNumberLiteral 1))
)
, ( Value.LiteralPattern () (StringLiteral "Bar")
, Value.Literal () (BoolLiteral False)
)
]
)
(Value.PatternMatch ()
var
[ ( Value.LiteralPattern () (StringLiteral "Foo")
, Value.Literal () (BoolLiteral True)
)
, ( Value.LiteralPattern () (StringLiteral "Bar")
, Value.Literal () (BoolLiteral False)
)
]
)
, positiveCheck "case var of \"Foo\" -> int1 == 1 _ -> False = case var of \"Foo\" -> True _ -> False"
(Value.PatternMatch ()
var
[ ( Value.LiteralPattern () (StringLiteral "Foo")
, Value.Apply () (Value.Apply () (Value.Reference () (fqn "Morphir.SDK" "Basics" "equal")) int1) (Value.Literal () (WholeNumberLiteral 1))
)
, ( Value.WildcardPattern ()
, Value.Literal () (BoolLiteral False)
)
]
)
(Value.PatternMatch ()
var
[ ( Value.LiteralPattern () (StringLiteral "Foo")
, Value.Literal () (BoolLiteral True)
)
, ( Value.WildcardPattern ()
, Value.Literal () (BoolLiteral False)
)
]
)
, {- Basics.identity -}
positiveCheck "identity var = var"
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "Basics" "identity"))
var
)
var
, positiveCheck "identity [var,\"b\",\"123\"] = [var,\"b\",\"123\"]"
(Value.Apply ()
(Value.Reference () (fqn "Morphir.SDK" "Basics" "identity"))
(Value.List () [ var, Value.Literal () (StringLiteral "b"), Value.Literal () (StringLiteral "123") ])
)
(Value.List () [ var, Value.Literal () (StringLiteral "b"), Value.Literal () (StringLiteral "123") ])
]
Loading