From d6a79cb193dbda9bac3774c70651945c51216037 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Wed, 23 Mar 2022 02:58:54 +0300 Subject: [PATCH 1/3] add beta reduction --- LambdaInterpreter/LambdaInterpreter.sln | 16 ++++++++ .../LambdaInterpreter.fsproj | 13 +++++++ .../LambdaInterpreter/Program.fs | 38 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 LambdaInterpreter/LambdaInterpreter.sln create mode 100644 LambdaInterpreter/LambdaInterpreter/LambdaInterpreter.fsproj create mode 100644 LambdaInterpreter/LambdaInterpreter/Program.fs diff --git a/LambdaInterpreter/LambdaInterpreter.sln b/LambdaInterpreter/LambdaInterpreter.sln new file mode 100644 index 0000000..317fdbc --- /dev/null +++ b/LambdaInterpreter/LambdaInterpreter.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LambdaInterpreter", "LambdaInterpreter\LambdaInterpreter.fsproj", "{81D87A95-7386-4009-9E71-1E58B5966D23}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {81D87A95-7386-4009-9E71-1E58B5966D23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81D87A95-7386-4009-9E71-1E58B5966D23}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81D87A95-7386-4009-9E71-1E58B5966D23}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81D87A95-7386-4009-9E71-1E58B5966D23}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/LambdaInterpreter/LambdaInterpreter/LambdaInterpreter.fsproj b/LambdaInterpreter/LambdaInterpreter/LambdaInterpreter.fsproj new file mode 100644 index 0000000..761405f --- /dev/null +++ b/LambdaInterpreter/LambdaInterpreter/LambdaInterpreter.fsproj @@ -0,0 +1,13 @@ + + + + Exe + net6.0 + Windows + + + + + + + diff --git a/LambdaInterpreter/LambdaInterpreter/Program.fs b/LambdaInterpreter/LambdaInterpreter/Program.fs new file mode 100644 index 0000000..55850c7 --- /dev/null +++ b/LambdaInterpreter/LambdaInterpreter/Program.fs @@ -0,0 +1,38 @@ +open System +open System.Collections.Generic +open System.Security.Principal + +type Term = + | Variable of int + | Application of Term * Term + | LambdaAbstraction of int * Term + +let getVar term = + let rec execute term list = + match term with + | Variable(v) -> v :: list + | Application(term1, term2) -> (execute term1 list) @ (execute term2 list) + | LambdaAbstraction(v, term1) -> execute term1 (List.filter(fun x -> x <> v) list) + execute term [] +let checkFreeVar var term = List.exists(fun x -> x = var) (getVar term) + +let rec substitution var termOut termIn = + match termOut with + | Variable(v) -> if v = var then termOut else Variable(var) + | Application(termApp1, termApp2) -> Application(substitution var termApp1 termIn, substitution var termApp2 termIn) + | LambdaAbstraction(var1, term1) -> + match var1 with + | v when var = v -> LambdaAbstraction(var1, term1) + | v when (checkFreeVar var1 termIn) || (checkFreeVar var term1) -> LambdaAbstraction(var1, (substitution var term1 termIn)) + | _ -> + // + // + // + + +let rec betaReduction term = + match term with + | Variable(v) -> Variable(v) + | Application(LambdaAbstraction(v, term), termForSubstitution) -> betaReduction (substitution v term termForSubstitution) + | Application(term1, term2) -> Application(betaReduction term1, betaReduction term2) + | LambdaAbstraction(v, term) -> LambdaAbstraction(v, betaReduction term) From ede1e8f760d46b71d59234993c059e80379e7595 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Wed, 23 Mar 2022 12:44:04 +0300 Subject: [PATCH 2/3] add some tests --- .../LambdaInterpreter.Test.fsproj | 26 +++++++++++++++++ .../LambdaInterpreter.Test/UnitTest1.fs | 29 +++++++++++++++++++ LambdaInterpreter/LambdaInterpreter.sln | 6 ++++ .../LambdaInterpreter/Program.fs | 23 ++++++++------- 4 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreter.Test.fsproj create mode 100644 LambdaInterpreter/LambdaInterpreter.Test/UnitTest1.fs diff --git a/LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreter.Test.fsproj b/LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreter.Test.fsproj new file mode 100644 index 0000000..233564e --- /dev/null +++ b/LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreter.Test.fsproj @@ -0,0 +1,26 @@ + + + + net6.0 + + false + false + + + + + + + + + + + + + + + + + + + diff --git a/LambdaInterpreter/LambdaInterpreter.Test/UnitTest1.fs b/LambdaInterpreter/LambdaInterpreter.Test/UnitTest1.fs new file mode 100644 index 0000000..0bfad9e --- /dev/null +++ b/LambdaInterpreter/LambdaInterpreter.Test/UnitTest1.fs @@ -0,0 +1,29 @@ +module LambdaInterpreter.Test + +open NUnit.Framework +open FsUnit +open Program + +[] +let TestAppWithVarTerm () = + let term = Term.Application(LambdaAbstraction("y", Variable("y")), Variable("z")) + + let result = betaReduction term + + result |> should equal (Variable("z")) + +[] +let TestAppWithTwoTerm () = + let term = Term.Application(LambdaAbstraction("y", Variable("y")), LambdaAbstraction("z", Variable("z"))) + + let result = term |> betaReduction + + result |> should equal (LambdaAbstraction("z", Variable("z"))) + +[] +let TestLambdaAbs () = + let term = Term.LambdaAbstraction("x", LambdaAbstraction("z", Variable("z"))) + + let result = term |> betaReduction + + result |> should equal (LambdaAbstraction("x", LambdaAbstraction("z", Variable("z")))) \ No newline at end of file diff --git a/LambdaInterpreter/LambdaInterpreter.sln b/LambdaInterpreter/LambdaInterpreter.sln index 317fdbc..07c0101 100644 --- a/LambdaInterpreter/LambdaInterpreter.sln +++ b/LambdaInterpreter/LambdaInterpreter.sln @@ -2,6 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LambdaInterpreter", "LambdaInterpreter\LambdaInterpreter.fsproj", "{81D87A95-7386-4009-9E71-1E58B5966D23}" EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LambdaInterpreter.Test", "LambdaInterpreter.Test\LambdaInterpreter.Test.fsproj", "{0D2BE233-2834-448C-A50E-4644123FA525}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -12,5 +14,9 @@ Global {81D87A95-7386-4009-9E71-1E58B5966D23}.Debug|Any CPU.Build.0 = Debug|Any CPU {81D87A95-7386-4009-9E71-1E58B5966D23}.Release|Any CPU.ActiveCfg = Release|Any CPU {81D87A95-7386-4009-9E71-1E58B5966D23}.Release|Any CPU.Build.0 = Release|Any CPU + {0D2BE233-2834-448C-A50E-4644123FA525}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0D2BE233-2834-448C-A50E-4644123FA525}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0D2BE233-2834-448C-A50E-4644123FA525}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0D2BE233-2834-448C-A50E-4644123FA525}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/LambdaInterpreter/LambdaInterpreter/Program.fs b/LambdaInterpreter/LambdaInterpreter/Program.fs index 55850c7..25854ea 100644 --- a/LambdaInterpreter/LambdaInterpreter/Program.fs +++ b/LambdaInterpreter/LambdaInterpreter/Program.fs @@ -3,9 +3,9 @@ open System.Collections.Generic open System.Security.Principal type Term = - | Variable of int + | Variable of string | Application of Term * Term - | LambdaAbstraction of int * Term + | LambdaAbstraction of string * Term let getVar term = let rec execute term list = @@ -14,20 +14,21 @@ let getVar term = | Application(term1, term2) -> (execute term1 list) @ (execute term2 list) | LambdaAbstraction(v, term1) -> execute term1 (List.filter(fun x -> x <> v) list) execute term [] -let checkFreeVar var term = List.exists(fun x -> x = var) (getVar term) +let checkFreeVar var term = term |> getVar |> List.exists(fun x -> x = var) let rec substitution var termOut termIn = match termOut with - | Variable(v) -> if v = var then termOut else Variable(var) + | Variable(v) -> if v = var then termIn else Variable(var) | Application(termApp1, termApp2) -> Application(substitution var termApp1 termIn, substitution var termApp2 termIn) - | LambdaAbstraction(var1, term1) -> - match var1 with - | v when var = v -> LambdaAbstraction(var1, term1) - | v when (checkFreeVar var1 termIn) || (checkFreeVar var term1) -> LambdaAbstraction(var1, (substitution var term1 termIn)) + | LambdaAbstraction(varInAbs, termInAbs) -> + match varInAbs with + | v when var = v -> LambdaAbstraction(varInAbs, termInAbs) + | v when (checkFreeVar varInAbs termIn) || (checkFreeVar var termInAbs) -> LambdaAbstraction(varInAbs, (substitution var termInAbs termIn)) | _ -> - // - // - // + let newVar = (((getVar termInAbs) @ (getVar termIn)) |> List.toArray |> Array.max) + "1" + let newTerm = newVar |> Variable + let termWithNewVar = substitution var termInAbs newTerm + LambdaAbstraction(newVar, substitution var termWithNewVar termIn ) let rec betaReduction term = From b05a0813e5f724de4c1f05116b328bd271c2a9be Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Wed, 23 Mar 2022 19:09:48 +0300 Subject: [PATCH 3/3] styleguide fix --- .../LambdaInterpreter.Test/LambdaInterpreter.Test.fsproj | 2 +- .../{UnitTest1.fs => LambdaInterpreterTest1.fs} | 0 LambdaInterpreter/LambdaInterpreter/Program.fs | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename LambdaInterpreter/LambdaInterpreter.Test/{UnitTest1.fs => LambdaInterpreterTest1.fs} (100%) diff --git a/LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreter.Test.fsproj b/LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreter.Test.fsproj index 233564e..71e94cd 100644 --- a/LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreter.Test.fsproj +++ b/LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreter.Test.fsproj @@ -8,7 +8,7 @@ - + diff --git a/LambdaInterpreter/LambdaInterpreter.Test/UnitTest1.fs b/LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreterTest1.fs similarity index 100% rename from LambdaInterpreter/LambdaInterpreter.Test/UnitTest1.fs rename to LambdaInterpreter/LambdaInterpreter.Test/LambdaInterpreterTest1.fs diff --git a/LambdaInterpreter/LambdaInterpreter/Program.fs b/LambdaInterpreter/LambdaInterpreter/Program.fs index 25854ea..91dee12 100644 --- a/LambdaInterpreter/LambdaInterpreter/Program.fs +++ b/LambdaInterpreter/LambdaInterpreter/Program.fs @@ -11,7 +11,7 @@ let getVar term = let rec execute term list = match term with | Variable(v) -> v :: list - | Application(term1, term2) -> (execute term1 list) @ (execute term2 list) + | Application(term1, term2) -> List.append (execute term1 list) (execute term2 list) | LambdaAbstraction(v, term1) -> execute term1 (List.filter(fun x -> x <> v) list) execute term [] let checkFreeVar var term = term |> getVar |> List.exists(fun x -> x = var)