Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ init:

environment:
matrix:
- solution: Semester4/NetworkModel/NetworkModel.sln
- solution: Semester4/Interpreter/Interpreter.sln

before_build:
- nuget restore %solution%
Expand Down
22 changes: 22 additions & 0 deletions semester4/Interpreter/Interpreter.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Interpreter", "Interpreter\Interpreter.fsproj", "{F4AC6C26-010E-4A43-9A7E-DE86E607064B}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "InterpreterTests", "InterpreterTests\InterpreterTests.fsproj", "{B0759521-85A7-4058-A22F-DAC2B0BC2EAE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F4AC6C26-010E-4A43-9A7E-DE86E607064B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F4AC6C26-010E-4A43-9A7E-DE86E607064B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F4AC6C26-010E-4A43-9A7E-DE86E607064B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F4AC6C26-010E-4A43-9A7E-DE86E607064B}.Release|Any CPU.Build.0 = Release|Any CPU
{B0759521-85A7-4058-A22F-DAC2B0BC2EAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0759521-85A7-4058-A22F-DAC2B0BC2EAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0759521-85A7-4058-A22F-DAC2B0BC2EAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0759521-85A7-4058-A22F-DAC2B0BC2EAE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
54 changes: 54 additions & 0 deletions semester4/Interpreter/Interpreter/Interpreter.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module Interpreter

/// Лямбда-терм, бывает трёх видов
type Term =
| Variable of char
| Abstraction of char * Term
| Application of Term * Term

/// Свободна переменная в выражении или нет
let rec isFree expression variable =
match expression with
| Variable var -> var = variable
| Abstraction (var, term) -> var <> variable && isFree term variable
| Application (left, right) -> isFree left variable || isFree right variable

/// Замена переменной в выражении
let rec substitution oldVariable newVariable expression =

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newVariable --- не лучшее название для подставляемого вместо переменной терма. Может показаться, что он может быть только переменной

let vars = [ 'a' .. 'z' ]
match expression with
| Variable var when var = oldVariable -> newVariable
| Variable _ -> expression
| Abstraction (var, _) when var = oldVariable -> expression
| Abstraction (var, term) when not <| isFree newVariable var ->
Abstraction(var, substitution oldVariable newVariable term)
| Abstraction (var, term) ->
let newSymbol =
vars
|> List.filter (not << isFree newVariable)
|> List.head

Abstraction
(newSymbol,
substitution oldVariable newVariable
<| substitution var (Variable newSymbol) term)
| Application (left, right) ->
Application(substitution oldVariable newVariable left, substitution oldVariable newVariable right)

/// Бета-редукция выражения
let betaReduction (term: Term) =
let rec betaReductionRec term =
match term with
| Variable var -> Variable(var)
| Abstraction (var, term) -> Abstraction(var, betaReductionRec <| term)
| Application (Abstraction (var, leftTerm), rightTerm) ->
leftTerm
|> substitution var rightTerm
|> betaReductionRec
| Application (left, right) ->
let leftReduce = betaReductionRec left
match leftReduce with
| Abstraction (_) -> Application(leftReduce, right) |> betaReductionRec
| _ -> Application(leftReduce, betaReductionRec right)

betaReductionRec term
11 changes: 11 additions & 0 deletions semester4/Interpreter/Interpreter/Interpreter.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="Interpreter.fs" />
</ItemGroup>

</Project>
44 changes: 44 additions & 0 deletions semester4/Interpreter/InterpreterTests/InterpreterTest.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module InterpreterTests

open NUnit.Framework
open FsUnit
open Interpreter

[<Test>]
let ``simple variable test`` () =
Variable('x')
|> betaReduction
|> should equal (Variable('x'))

[<Test>]
let ``simple abstraction test`` () =
Abstraction('x', Variable('x'))
|> betaReduction
|> should equal (Abstraction('x', Variable('x')))

[<Test>]
let ``simple application test`` () =
Application(Variable('x'), Variable('y'))
|> betaReduction
|> should equal (Application(Variable('x'), Variable('y')))

// (λx.x y)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вообще, выражение за лямбдой --- это термы справа до скобки, так что тут имелось в виду (λx.x) y. В тестах ниже тоже. Это запутывает

[<Test>]
let ``simple test`` () =
Application(Abstraction('x', Variable('x')), Variable('y'))
|> betaReduction
|> should equal (Variable('y'))

// λx.(x y) z
[<Test>]
let ``simple test two`` () =
Application(Abstraction('x', Application(Variable('x'), Variable('y'))), Variable('z'))
|> betaReduction
|> should equal (Application(Variable('z'), Variable('y')))

// (λx.y z) (λa.(a z) b)
[<Test>]
let ``simple test three`` () =
Application(Application(Abstraction('x', Variable('y')), Variable('z')), Application(Abstraction('a', Application(Variable('a'), Variable('z'))), Variable('b')))
|> betaReduction
|> should equal (Application(Variable('y'), Application(Variable('b'), Variable('z'))))
25 changes: 25 additions & 0 deletions semester4/Interpreter/InterpreterTests/InterpreterTests.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>

<IsPackable>true</IsPackable>
<GenerateProgramFile>true</GenerateProgramFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FsUnit" Version="4.0.1" />
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
</ItemGroup>

<ItemGroup>
<Compile Include="InterpreterTest.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Interpreter\Interpreter.fsproj" />
</ItemGroup>

</Project>