Skip to content
This repository has been archived by the owner on May 20, 2018. It is now read-only.

Embedded terms #174

Merged
merged 51 commits into from
Dec 20, 2015
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
4af80b1
Add an `Embedded` case to `Expression`.
robrix Dec 13, 2015
701df01
Check that the annotations on embedded terms are types.
robrix Dec 13, 2015
1f2978e
Add a convenience constructor for Embedded Terms.
robrix Dec 13, 2015
b6c87a8
Add a convenience constructor for Embedded Terms of Embedded types.
robrix Dec 13, 2015
6937007
Add a convenience constructor for Embedded types.
robrix Dec 13, 2015
1ecc07a
Use the Embedded type constructor in the Embedded value constructor.
robrix Dec 13, 2015
bf2db11
Stub in a String module.
robrix Dec 13, 2015
d3ee938
Embed a String type.
robrix Dec 13, 2015
6a35963
Add the String module to the directory.
robrix Dec 13, 2015
c3f7d8d
Embed a Character type.
robrix Dec 13, 2015
89e9c0f
Add some references to List module terms.
robrix Dec 13, 2015
f15503b
Write a function to construct a List Character from a String.
robrix Dec 13, 2015
7bbd346
Add a binding toList : String → List Character.
robrix Dec 13, 2015
ccfd1db
Single-quote embedded values.
robrix Dec 13, 2015
3e03987
Judge any two Embedded values with the same dynamic & annotated types…
robrix Dec 13, 2015
a6c161a
Use a single code path for Embedded Term construction.
robrix Dec 13, 2015
59f2a80
Generalize Embedded Term construction.
robrix Dec 13, 2015
216e058
Add an Embedded constructor taking an equality function.
robrix Dec 13, 2015
299a863
Embed an equality function alongside the value.
robrix Dec 13, 2015
7619047
Spacing.
robrix Dec 13, 2015
2904ad9
Use guard clauses to tidy up evaluation.
robrix Dec 13, 2015
61b0a1e
Log both the original term and its evaluated form in illegal applicat…
robrix Dec 13, 2015
0d46ab8
Rephrase Application evaluation as a nested switch.
robrix Dec 13, 2015
aa927f7
Evaluate embedded functions of type `Term throws -> Term`.
robrix Dec 13, 2015
789305f
Add a Term constructor embedding named evaluator functions.
robrix Dec 13, 2015
33e36a5
Evaluation expects evaluator terms to be named.
robrix Dec 13, 2015
5444d4b
Correct the construction of Embedded types to not use the Optional ==…
robrix Dec 13, 2015
ff5bdbe
Add a convenience to embed characters with the defined type.
robrix Dec 13, 2015
808e1dc
A more concise `toTerm` function.
robrix Dec 13, 2015
67dc771
Add an Embedded Term constructor which automatically unwraps host val…
robrix Dec 13, 2015
6fc6c5d
Let the type remain tacit.
robrix Dec 13, 2015
1fd3c40
Define toList by embedding.
robrix Dec 13, 2015
57b6b7e
Test that `toList` constructs strings correctly.
robrix Dec 13, 2015
c112963
Stub in a `fromList` definition.
robrix Dec 13, 2015
cf26156
Move `embedCharacter` into a private global.
robrix Dec 13, 2015
4a90066
We need to quote the type name here.
robrix Dec 13, 2015
4b2bb29
We don’t need to namespace here.
robrix Dec 13, 2015
edb766c
Just quote the type name directly.
robrix Dec 13, 2015
8d9144d
Normalize the error against the others.
robrix Dec 13, 2015
a1927d1
Test the conversion of empty lists to strings.
robrix Dec 18, 2015
6b722db
Test the operation of `List` values as eliminators.
robrix Dec 18, 2015
975a9a7
Rename `a` to `aʹ`.
robrix Dec 19, 2015
2c40b73
Substitution does not replace shadowed variables.
robrix Dec 20, 2015
1e8ec9a
Correct which value we log for illegal applications.
robrix Dec 20, 2015
70d1578
Remove an extra lambda in `Sigma.second`.
robrix Dec 20, 2015
bb2b0e9
Carry the `visited` set into recursive invocations correctly.
robrix Dec 20, 2015
aed04f2
Definitional equality does not use the visited set.
robrix Dec 20, 2015
cad85c3
Weak head normal form does not use the visited set.
robrix Dec 20, 2015
4bc82fb
Define `fromList` via a helper function, `combine`.
robrix Dec 20, 2015
109c25f
Test `fromList` against a single-character list.
robrix Dec 20, 2015
295d5e8
Test `fromList` against a multiple-character list.
robrix Dec 20, 2015
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
4 changes: 4 additions & 0 deletions Manifold.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
D415A09B1B51EFDE001C15E5 /* Term+Construction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D415A09A1B51EFDE001C15E5 /* Term+Construction.swift */; };
D43AC8831BC1824D008762B7 /* Telescope.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43AC8821BC1824D008762B7 /* Telescope.swift */; };
D43B6D1B1C1DB2CA008EF3D2 /* Module+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43B6D1A1C1DB2CA008EF3D2 /* Module+String.swift */; };
D445417C1BCAB0C100F2946D /* Module+Unit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D445417B1BCAB0C100F2946D /* Module+Unit.swift */; };
D44541801BCAC38500F2946D /* Module+List.swift in Sources */ = {isa = PBXBuildFile; fileRef = D445417F1BCAC38500F2946D /* Module+List.swift */; };
D44541841BCAEDCD00F2946D /* Term+WeakHeadNormalForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44541831BCAEDCD00F2946D /* Term+WeakHeadNormalForm.swift */; };
Expand Down Expand Up @@ -69,6 +70,7 @@
/* Begin PBXFileReference section */
D415A09A1B51EFDE001C15E5 /* Term+Construction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Term+Construction.swift"; sourceTree = "<group>"; };
D43AC8821BC1824D008762B7 /* Telescope.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Telescope.swift; sourceTree = "<group>"; };
D43B6D1A1C1DB2CA008EF3D2 /* Module+String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Module+String.swift"; sourceTree = "<group>"; };
D445417B1BCAB0C100F2946D /* Module+Unit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Module+Unit.swift"; sourceTree = "<group>"; };
D445417F1BCAC38500F2946D /* Module+List.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Module+List.swift"; sourceTree = "<group>"; };
D44541831BCAEDCD00F2946D /* Term+WeakHeadNormalForm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Term+WeakHeadNormalForm.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -241,6 +243,7 @@
D470CB971BDC27130003A931 /* Module+Vector.swift */,
D4ACE90C1BDC7E51009E928F /* Module+FiniteSet.swift */,
D4FB2D0A1BE44DAF00B3CCE0 /* Module+Functor.swift */,
D43B6D1A1C1DB2CA008EF3D2 /* Module+String.swift */,
);
name = Modules;
sourceTree = "<group>";
Expand Down Expand Up @@ -355,6 +358,7 @@
files = (
D445417C1BCAB0C100F2946D /* Module+Unit.swift in Sources */,
D4E9901C1BD3431D00F00CA7 /* Module+Either.swift in Sources */,
D43B6D1B1C1DB2CA008EF3D2 /* Module+String.swift in Sources */,
D415A09B1B51EFDE001C15E5 /* Term+Construction.swift in Sources */,
D44541901BCB028A00F2946D /* TermContainerType+CustomDebugStringConvertible.swift in Sources */,
D44541841BCAEDCD00F2946D /* Term+WeakHeadNormalForm.swift in Sources */,
Expand Down
5 changes: 5 additions & 0 deletions Manifold/Expression.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public enum Expression<Recur> {
case Variable(Name)
case Application(Recur, Recur)
case Lambda(Int, Recur?, Recur)
case Embedded(Any, (Any, Any) -> Bool, Recur)


// MARK: Functor
Expand All @@ -19,6 +20,8 @@ public enum Expression<Recur> {
return try .Application(transform(a), transform(b))
case let .Lambda(i, a, b):
return try .Lambda(i, a.map(transform), transform(b))
case let .Embedded(a, eq, b):
return try .Embedded(a, eq, transform(b))
}
}

Expand All @@ -35,6 +38,8 @@ public enum Expression<Recur> {
return equal(t1, u1) && equal(t2, u2)
case let (.Lambda(i, t, a), .Lambda(j, u, b)):
return i == j && ((t &&& u).map(equal) ?? (t == nil && u == nil)) && equal(a, b)
case let (.Embedded(a, eq, t1), .Embedded(b, _, t2)) where a.dynamicType == b.dynamicType:
return eq(a, b) && equal(t1, t2)
default:
return false
}
Expand Down
1 change: 1 addition & 0 deletions Manifold/Module+Directory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ extension Module {
sigma,
vector,
finiteSet,
string,
].map { ($0.name, $0) })
}
35 changes: 35 additions & 0 deletions Manifold/Module+String.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright © 2015 Rob Rix. All rights reserved.

extension Module {
public static var string: Module {
let List: Term = "List"
let cons: Term = "cons"
let `nil`: Term = "nil"

let String = Declaration("String",
type: .Type,
value: .Embedded(Swift.String.self))

let Character = Declaration("Character",
type: .Type,
value: .Embedded(Swift.Character.self))

func toTerm(characters: Swift.String.CharacterView) -> Term {
switch characters.first {
case let .Some(c):
return cons[Character.ref, .Embedded(c), toTerm(characters.dropFirst())]
default:
return `nil`[Character.ref]
}
}

let toList = Declaration("toList",
type: String.ref --> List[Character.ref],
value: () => { (string: Term) -> Term in
guard case let .Embedded(value as Swift.String, _, _) = string.out else { return ("toList" as Term)[string] }
return toTerm(value.characters)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is incorrect.

We evaluate this function when the value term is constructed, not when the defined toList term is evaluated. Therefore, it always fails the guard clause, produces itself in neutral form, and diverges during evaluation.

})

return Module("String", [ list ], [ String, Character, toList ])
}
}
20 changes: 20 additions & 0 deletions Manifold/Term+Construction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ extension Term {
return Term(.Lambda(i, type, body))
}

public static func Embedded<A>(value: A, _ equal: (A, A) -> Bool, _ type: Term) -> Term {
let equal: (Any, Any) -> Bool = { a, b in
guard let a = a as? A, b = b as? A else { return false }
return equal(a, b)
}
return Term(.Embedded(value as Any, equal, type))
}

public static func Embedded<A: Equatable>(value: A, _ type: Term) -> Term {
return .Embedded(value, ==, type)
}

public static func Embedded<A: Equatable>(value: A) -> Term {
return .Embedded(value, .Embedded(A.self))
}

public static func Embedded<A: Equatable>(type: A.Type) -> Term {
return .Embedded(A.self, ==, .Type)
}


public subscript (operands: Term...) -> Term {
return operands.reduce(self, combine: Term.Application)
Expand Down
4 changes: 4 additions & 0 deletions Manifold/Term+Elaboration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ extension Term {
let bʹ = try b.elaborateType(nil, environment, context + [ .Local(i): a ])
return .Unroll(a => { bʹ.annotation.substitute(i, $0) }, .Lambda(i, aʹ, bʹ))

case let (.Embedded(value, eq, type), .None):
let typeʹ = try type.elaborateType(.Type, environment, context)
return .Unroll(type, .Embedded(value, eq, typeʹ))

case let (.Type(m), .Some(.Type(n))) where n > m:
return try elaborateType(nil, environment, context)

Expand Down
2 changes: 2 additions & 0 deletions Manifold/TermContainerType+CustomDebugStringConvertible.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ extension TermContainerType {
return ".Application(\(a), \(b))"
case let .Lambda(i, a, b):
return ".Lambda(\(i), \(a), \(b))"
case let .Embedded(value, eq, type):
return ".Embedded(\(String(reflecting: value)), \(String(reflecting: eq)), \(type))"
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions Manifold/TermContainerType+CustomStringConvertible.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ extension TermContainerType {

case let .Lambda(variable, _, (_, (body, _))):
return ("λ \(Name.Local(variable)) . \(body)", true)

case let .Embedded(value, _, (_, (type, _))):
return ("'\(value)' : \(type)", true)
}
}
return out
Expand Down
4 changes: 4 additions & 0 deletions Manifold/TermContainerType+FreeVariables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ extension TermContainerType {
return i < 0 ? max(a, b) : max(i, a)
case let .Lambda(i, .None, b):
return i < 0 ? b : i
case let .Embedded(_, _, type):
return type
}
}
}
Expand All @@ -29,6 +31,8 @@ extension TermContainerType {
return a + b
case let .Lambda(i, a, b):
return (a ?? []) + b.filter { $0 != i }
case let .Embedded(_, _, type):
return type
}
}
}
Expand Down