This repository has no description www.jonmsterling.com/01HC/
dependent-types proof-assistant swift
3

Configure Feed

Select the types of activity you want to include in your feed.

First cut at core syntax, semantic domain, glued NbE.

Jon Sterling (Oct 5, 2025, 6:32 PM +0100) 5b19b15b

+955
+13
.gitignore
··· 1 + # SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + # 3 + # SPDX-License-Identifier: MPL-2.0 4 + 5 + .DS_Store 6 + /.build 7 + /Packages 8 + xcuserdata/ 9 + DerivedData/ 10 + .swiftpm/configuration/registries.json 11 + .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 12 + .netrc 13 + Package.resolved
+77
.swift-format
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + { 5 + "fileScopedDeclarationPrivacy" : { 6 + "accessLevel" : "private" 7 + }, 8 + "indentConditionalCompilationBlocks" : true, 9 + "indentSwitchCaseLabels" : false, 10 + "indentation" : { 11 + "tabs" : 1 12 + }, 13 + "lineBreakAroundMultilineExpressionChainComponents" : false, 14 + "lineBreakBeforeControlFlowKeywords" : false, 15 + "lineBreakBeforeEachArgument" : false, 16 + "lineBreakBeforeEachGenericRequirement" : false, 17 + "lineBreakBetweenDeclarationAttributes" : false, 18 + "lineLength" : 200, 19 + "maximumBlankLines" : 10, 20 + "multiElementCollectionTrailingCommas" : false, 21 + "noAssignmentInExpressions" : { 22 + "allowedFunctions" : [ 23 + "XCTAssertNoThrow" 24 + ] 25 + }, 26 + "prioritizeKeepingFunctionOutputTogether" : false, 27 + "reflowMultilineStringLiterals" : "never", 28 + "respectsExistingLineBreaks" : true, 29 + "rules" : { 30 + "AllPublicDeclarationsHaveDocumentation" : false, 31 + "AlwaysUseLiteralForEmptyCollectionInit" : false, 32 + "AlwaysUseLowerCamelCase" : true, 33 + "AmbiguousTrailingClosureOverload" : true, 34 + "AvoidRetroactiveConformances" : true, 35 + "BeginDocumentationCommentWithOneLineSummary" : false, 36 + "DoNotUseSemicolons" : true, 37 + "DontRepeatTypeInStaticProperties" : true, 38 + "FileScopedDeclarationPrivacy" : true, 39 + "FullyIndirectEnum" : true, 40 + "GroupNumericLiterals" : true, 41 + "IdentifiersMustBeASCII" : false, 42 + "NeverForceUnwrap" : false, 43 + "NeverUseForceTry" : false, 44 + "NeverUseImplicitlyUnwrappedOptionals" : false, 45 + "NoAccessLevelOnExtensionDeclaration" : true, 46 + "NoAssignmentInExpressions" : true, 47 + "NoBlockComments" : false, 48 + "NoCasesWithOnlyFallthrough" : true, 49 + "NoEmptyLinesOpeningClosingBraces" : false, 50 + "NoEmptyTrailingClosureParentheses" : true, 51 + "NoLabelsInCasePatterns" : true, 52 + "NoLeadingUnderscores" : false, 53 + "NoParensAroundConditions" : true, 54 + "NoPlaygroundLiterals" : true, 55 + "NoVoidReturnOnFunctionSignature" : true, 56 + "OmitExplicitReturns" : false, 57 + "OneCasePerLine" : true, 58 + "OneVariableDeclarationPerLine" : true, 59 + "OnlyOneTrailingClosureArgument" : true, 60 + "OrderedImports" : true, 61 + "ReplaceForEachWithForLoop" : true, 62 + "ReturnVoidInsteadOfEmptyTuple" : true, 63 + "TypeNamesShouldBeCapitalized" : true, 64 + "UseEarlyExits" : false, 65 + "UseExplicitNilCheckInConditions" : true, 66 + "UseLetInEveryBoundCaseVariable" : false, 67 + "UseShorthandTypeNames" : true, 68 + "UseSingleLinePropertyGetter" : true, 69 + "UseSynthesizedInitializer" : true, 70 + "UseTripleSlashForDocumentationComments" : true, 71 + "UseWhereClausesInForLoops" : false, 72 + "ValidateDocumentationComments" : false 73 + }, 74 + "spacesAroundRangeFormationOperators" : false, 75 + "spacesBeforeEndOfLineComments" : 2, 76 + "version" : 1 77 + }
+373
LICENSES/MPL-2.0.txt
··· 1 + Mozilla Public License Version 2.0 2 + ================================== 3 + 4 + 1. Definitions 5 + -------------- 6 + 7 + 1.1. "Contributor" 8 + means each individual or legal entity that creates, contributes to 9 + the creation of, or owns Covered Software. 10 + 11 + 1.2. "Contributor Version" 12 + means the combination of the Contributions of others (if any) used 13 + by a Contributor and that particular Contributor's Contribution. 14 + 15 + 1.3. "Contribution" 16 + means Covered Software of a particular Contributor. 17 + 18 + 1.4. "Covered Software" 19 + means Source Code Form to which the initial Contributor has attached 20 + the notice in Exhibit A, the Executable Form of such Source Code 21 + Form, and Modifications of such Source Code Form, in each case 22 + including portions thereof. 23 + 24 + 1.5. "Incompatible With Secondary Licenses" 25 + means 26 + 27 + (a) that the initial Contributor has attached the notice described 28 + in Exhibit B to the Covered Software; or 29 + 30 + (b) that the Covered Software was made available under the terms of 31 + version 1.1 or earlier of the License, but not also under the 32 + terms of a Secondary License. 33 + 34 + 1.6. "Executable Form" 35 + means any form of the work other than Source Code Form. 36 + 37 + 1.7. "Larger Work" 38 + means a work that combines Covered Software with other material, in 39 + a separate file or files, that is not Covered Software. 40 + 41 + 1.8. "License" 42 + means this document. 43 + 44 + 1.9. "Licensable" 45 + means having the right to grant, to the maximum extent possible, 46 + whether at the time of the initial grant or subsequently, any and 47 + all of the rights conveyed by this License. 48 + 49 + 1.10. "Modifications" 50 + means any of the following: 51 + 52 + (a) any file in Source Code Form that results from an addition to, 53 + deletion from, or modification of the contents of Covered 54 + Software; or 55 + 56 + (b) any new file in Source Code Form that contains any Covered 57 + Software. 58 + 59 + 1.11. "Patent Claims" of a Contributor 60 + means any patent claim(s), including without limitation, method, 61 + process, and apparatus claims, in any patent Licensable by such 62 + Contributor that would be infringed, but for the grant of the 63 + License, by the making, using, selling, offering for sale, having 64 + made, import, or transfer of either its Contributions or its 65 + Contributor Version. 66 + 67 + 1.12. "Secondary License" 68 + means either the GNU General Public License, Version 2.0, the GNU 69 + Lesser General Public License, Version 2.1, the GNU Affero General 70 + Public License, Version 3.0, or any later versions of those 71 + licenses. 72 + 73 + 1.13. "Source Code Form" 74 + means the form of the work preferred for making modifications. 75 + 76 + 1.14. "You" (or "Your") 77 + means an individual or a legal entity exercising rights under this 78 + License. For legal entities, "You" includes any entity that 79 + controls, is controlled by, or is under common control with You. For 80 + purposes of this definition, "control" means (a) the power, direct 81 + or indirect, to cause the direction or management of such entity, 82 + whether by contract or otherwise, or (b) ownership of more than 83 + fifty percent (50%) of the outstanding shares or beneficial 84 + ownership of such entity. 85 + 86 + 2. License Grants and Conditions 87 + -------------------------------- 88 + 89 + 2.1. Grants 90 + 91 + Each Contributor hereby grants You a world-wide, royalty-free, 92 + non-exclusive license: 93 + 94 + (a) under intellectual property rights (other than patent or trademark) 95 + Licensable by such Contributor to use, reproduce, make available, 96 + modify, display, perform, distribute, and otherwise exploit its 97 + Contributions, either on an unmodified basis, with Modifications, or 98 + as part of a Larger Work; and 99 + 100 + (b) under Patent Claims of such Contributor to make, use, sell, offer 101 + for sale, have made, import, and otherwise transfer either its 102 + Contributions or its Contributor Version. 103 + 104 + 2.2. Effective Date 105 + 106 + The licenses granted in Section 2.1 with respect to any Contribution 107 + become effective for each Contribution on the date the Contributor first 108 + distributes such Contribution. 109 + 110 + 2.3. Limitations on Grant Scope 111 + 112 + The licenses granted in this Section 2 are the only rights granted under 113 + this License. No additional rights or licenses will be implied from the 114 + distribution or licensing of Covered Software under this License. 115 + Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 + Contributor: 117 + 118 + (a) for any code that a Contributor has removed from Covered Software; 119 + or 120 + 121 + (b) for infringements caused by: (i) Your and any other third party's 122 + modifications of Covered Software, or (ii) the combination of its 123 + Contributions with other software (except as part of its Contributor 124 + Version); or 125 + 126 + (c) under Patent Claims infringed by Covered Software in the absence of 127 + its Contributions. 128 + 129 + This License does not grant any rights in the trademarks, service marks, 130 + or logos of any Contributor (except as may be necessary to comply with 131 + the notice requirements in Section 3.4). 132 + 133 + 2.4. Subsequent Licenses 134 + 135 + No Contributor makes additional grants as a result of Your choice to 136 + distribute the Covered Software under a subsequent version of this 137 + License (see Section 10.2) or under the terms of a Secondary License (if 138 + permitted under the terms of Section 3.3). 139 + 140 + 2.5. Representation 141 + 142 + Each Contributor represents that the Contributor believes its 143 + Contributions are its original creation(s) or it has sufficient rights 144 + to grant the rights to its Contributions conveyed by this License. 145 + 146 + 2.6. Fair Use 147 + 148 + This License is not intended to limit any rights You have under 149 + applicable copyright doctrines of fair use, fair dealing, or other 150 + equivalents. 151 + 152 + 2.7. Conditions 153 + 154 + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 + in Section 2.1. 156 + 157 + 3. Responsibilities 158 + ------------------- 159 + 160 + 3.1. Distribution of Source Form 161 + 162 + All distribution of Covered Software in Source Code Form, including any 163 + Modifications that You create or to which You contribute, must be under 164 + the terms of this License. You must inform recipients that the Source 165 + Code Form of the Covered Software is governed by the terms of this 166 + License, and how they can obtain a copy of this License. You may not 167 + attempt to alter or restrict the recipients' rights in the Source Code 168 + Form. 169 + 170 + 3.2. Distribution of Executable Form 171 + 172 + If You distribute Covered Software in Executable Form then: 173 + 174 + (a) such Covered Software must also be made available in Source Code 175 + Form, as described in Section 3.1, and You must inform recipients of 176 + the Executable Form how they can obtain a copy of such Source Code 177 + Form by reasonable means in a timely manner, at a charge no more 178 + than the cost of distribution to the recipient; and 179 + 180 + (b) You may distribute such Executable Form under the terms of this 181 + License, or sublicense it under different terms, provided that the 182 + license for the Executable Form does not attempt to limit or alter 183 + the recipients' rights in the Source Code Form under this License. 184 + 185 + 3.3. Distribution of a Larger Work 186 + 187 + You may create and distribute a Larger Work under terms of Your choice, 188 + provided that You also comply with the requirements of this License for 189 + the Covered Software. If the Larger Work is a combination of Covered 190 + Software with a work governed by one or more Secondary Licenses, and the 191 + Covered Software is not Incompatible With Secondary Licenses, this 192 + License permits You to additionally distribute such Covered Software 193 + under the terms of such Secondary License(s), so that the recipient of 194 + the Larger Work may, at their option, further distribute the Covered 195 + Software under the terms of either this License or such Secondary 196 + License(s). 197 + 198 + 3.4. Notices 199 + 200 + You may not remove or alter the substance of any license notices 201 + (including copyright notices, patent notices, disclaimers of warranty, 202 + or limitations of liability) contained within the Source Code Form of 203 + the Covered Software, except that You may alter any license notices to 204 + the extent required to remedy known factual inaccuracies. 205 + 206 + 3.5. Application of Additional Terms 207 + 208 + You may choose to offer, and to charge a fee for, warranty, support, 209 + indemnity or liability obligations to one or more recipients of Covered 210 + Software. However, You may do so only on Your own behalf, and not on 211 + behalf of any Contributor. You must make it absolutely clear that any 212 + such warranty, support, indemnity, or liability obligation is offered by 213 + You alone, and You hereby agree to indemnify every Contributor for any 214 + liability incurred by such Contributor as a result of warranty, support, 215 + indemnity or liability terms You offer. You may include additional 216 + disclaimers of warranty and limitations of liability specific to any 217 + jurisdiction. 218 + 219 + 4. Inability to Comply Due to Statute or Regulation 220 + --------------------------------------------------- 221 + 222 + If it is impossible for You to comply with any of the terms of this 223 + License with respect to some or all of the Covered Software due to 224 + statute, judicial order, or regulation then You must: (a) comply with 225 + the terms of this License to the maximum extent possible; and (b) 226 + describe the limitations and the code they affect. Such description must 227 + be placed in a text file included with all distributions of the Covered 228 + Software under this License. Except to the extent prohibited by statute 229 + or regulation, such description must be sufficiently detailed for a 230 + recipient of ordinary skill to be able to understand it. 231 + 232 + 5. Termination 233 + -------------- 234 + 235 + 5.1. The rights granted under this License will terminate automatically 236 + if You fail to comply with any of its terms. However, if You become 237 + compliant, then the rights granted under this License from a particular 238 + Contributor are reinstated (a) provisionally, unless and until such 239 + Contributor explicitly and finally terminates Your grants, and (b) on an 240 + ongoing basis, if such Contributor fails to notify You of the 241 + non-compliance by some reasonable means prior to 60 days after You have 242 + come back into compliance. Moreover, Your grants from a particular 243 + Contributor are reinstated on an ongoing basis if such Contributor 244 + notifies You of the non-compliance by some reasonable means, this is the 245 + first time You have received notice of non-compliance with this License 246 + from such Contributor, and You become compliant prior to 30 days after 247 + Your receipt of the notice. 248 + 249 + 5.2. If You initiate litigation against any entity by asserting a patent 250 + infringement claim (excluding declaratory judgment actions, 251 + counter-claims, and cross-claims) alleging that a Contributor Version 252 + directly or indirectly infringes any patent, then the rights granted to 253 + You by any and all Contributors for the Covered Software under Section 254 + 2.1 of this License shall terminate. 255 + 256 + 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 + end user license agreements (excluding distributors and resellers) which 258 + have been validly granted by You or Your distributors under this License 259 + prior to termination shall survive termination. 260 + 261 + ************************************************************************ 262 + * * 263 + * 6. Disclaimer of Warranty * 264 + * ------------------------- * 265 + * * 266 + * Covered Software is provided under this License on an "as is" * 267 + * basis, without warranty of any kind, either expressed, implied, or * 268 + * statutory, including, without limitation, warranties that the * 269 + * Covered Software is free of defects, merchantable, fit for a * 270 + * particular purpose or non-infringing. The entire risk as to the * 271 + * quality and performance of the Covered Software is with You. * 272 + * Should any Covered Software prove defective in any respect, You * 273 + * (not any Contributor) assume the cost of any necessary servicing, * 274 + * repair, or correction. This disclaimer of warranty constitutes an * 275 + * essential part of this License. No use of any Covered Software is * 276 + * authorized under this License except under this disclaimer. * 277 + * * 278 + ************************************************************************ 279 + 280 + ************************************************************************ 281 + * * 282 + * 7. Limitation of Liability * 283 + * -------------------------- * 284 + * * 285 + * Under no circumstances and under no legal theory, whether tort * 286 + * (including negligence), contract, or otherwise, shall any * 287 + * Contributor, or anyone who distributes Covered Software as * 288 + * permitted above, be liable to You for any direct, indirect, * 289 + * special, incidental, or consequential damages of any character * 290 + * including, without limitation, damages for lost profits, loss of * 291 + * goodwill, work stoppage, computer failure or malfunction, or any * 292 + * and all other commercial damages or losses, even if such party * 293 + * shall have been informed of the possibility of such damages. This * 294 + * limitation of liability shall not apply to liability for death or * 295 + * personal injury resulting from such party's negligence to the * 296 + * extent applicable law prohibits such limitation. Some * 297 + * jurisdictions do not allow the exclusion or limitation of * 298 + * incidental or consequential damages, so this exclusion and * 299 + * limitation may not apply to You. * 300 + * * 301 + ************************************************************************ 302 + 303 + 8. Litigation 304 + ------------- 305 + 306 + Any litigation relating to this License may be brought only in the 307 + courts of a jurisdiction where the defendant maintains its principal 308 + place of business and such litigation shall be governed by laws of that 309 + jurisdiction, without reference to its conflict-of-law provisions. 310 + Nothing in this Section shall prevent a party's ability to bring 311 + cross-claims or counter-claims. 312 + 313 + 9. Miscellaneous 314 + ---------------- 315 + 316 + This License represents the complete agreement concerning the subject 317 + matter hereof. If any provision of this License is held to be 318 + unenforceable, such provision shall be reformed only to the extent 319 + necessary to make it enforceable. Any law or regulation which provides 320 + that the language of a contract shall be construed against the drafter 321 + shall not be used to construe this License against a Contributor. 322 + 323 + 10. Versions of the License 324 + --------------------------- 325 + 326 + 10.1. New Versions 327 + 328 + Mozilla Foundation is the license steward. Except as provided in Section 329 + 10.3, no one other than the license steward has the right to modify or 330 + publish new versions of this License. Each version will be given a 331 + distinguishing version number. 332 + 333 + 10.2. Effect of New Versions 334 + 335 + You may distribute the Covered Software under the terms of the version 336 + of the License under which You originally received the Covered Software, 337 + or under the terms of any subsequent version published by the license 338 + steward. 339 + 340 + 10.3. Modified Versions 341 + 342 + If you create software not governed by this License, and you want to 343 + create a new license for such software, you may create and use a 344 + modified version of this License if you rename the license and remove 345 + any references to the name of the license steward (except to note that 346 + such modified license differs from this License). 347 + 348 + 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 + Licenses 350 + 351 + If You choose to distribute Source Code Form that is Incompatible With 352 + Secondary Licenses under the terms of this version of the License, the 353 + notice described in Exhibit B of this License must be attached. 354 + 355 + Exhibit A - Source Code Form License Notice 356 + ------------------------------------------- 357 + 358 + This Source Code Form is subject to the terms of the Mozilla Public 359 + License, v. 2.0. If a copy of the MPL was not distributed with this 360 + file, You can obtain one at https://mozilla.org/MPL/2.0/. 361 + 362 + If it is not possible or desirable to put the notice in a particular 363 + file, then You may include the notice in a location (such as a LICENSE 364 + file in a relevant directory) where a recipient would be likely to look 365 + for such a notice. 366 + 367 + You may add additional accurate notices of copyright ownership. 368 + 369 + Exhibit B - "Incompatible With Secondary Licenses" Notice 370 + --------------------------------------------------------- 371 + 372 + This Source Code Form is "Incompatible With Secondary Licenses", as 373 + defined by the Mozilla Public License, v. 2.0.
+30
Package.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + // swift-tools-version: 6.2 6 + // The swift-tools-version declares the minimum version of Swift required to build this package. 7 + 8 + import PackageDescription 9 + 10 + let package = Package( 11 + name: "PterodactylKernel", 12 + products: [ 13 + // Products define the executables and libraries a package produces, making them visible to other packages. 14 + .library( 15 + name: "PterodactylKernel", 16 + targets: ["PterodactylKernel"] 17 + ) 18 + ], 19 + targets: [ 20 + // Targets are the basic building blocks of a package, defining a module or a test suite. 21 + // Targets can depend on other targets in this package and products from dependencies. 22 + .target( 23 + name: "PterodactylKernel", 24 + ), 25 + .testTarget( 26 + name: "PterodactylKernelTests", 27 + dependencies: ["PterodactylKernel"] 28 + ) 29 + ] 30 + )
+29
Sources/PterodactylKernel/Control/AsyncThunk.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + import Foundation 6 + 7 + actor AsyncThunk<Value> { 8 + private var storage: Value? 9 + private var thunk: (() async -> Value)? 10 + 11 + public init(thunk: @escaping @Sendable () async -> Value) { 12 + self.thunk = thunk 13 + } 14 + 15 + public init(value: Value) { 16 + self.storage = value 17 + } 18 + 19 + public func value() async -> Value { 20 + if let storage { return storage } 21 + if let thunk { 22 + let computed = await thunk() 23 + self.storage = computed 24 + self.thunk = nil 25 + return computed 26 + } 27 + fatalError("AsyncThunk has neither thunk nor storage.") 28 + } 29 + }
+28
Sources/PterodactylKernel/Core Types/FieldDict.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + import Foundation 6 + 7 + struct FieldDict<Value> { 8 + public let elements: [(String, Value)] 9 + 10 + init(_ dict: [(String, Value)]) { 11 + self.elements = dict 12 + } 13 + 14 + subscript(key: String) -> Value? { 15 + elements.first { $0.0 == key }?.1 16 + } 17 + } 18 + 19 + extension FieldDict: Sendable where Value: Sendable {} 20 + 21 + extension FieldDict { 22 + func map<U>(_ f: (Value) -> U) -> FieldDict<U> { 23 + let dict = elements.map { (k, v) in 24 + (k, f(v)) 25 + } 26 + return FieldDict<U>(dict) 27 + } 28 + }
+35
Sources/PterodactylKernel/Core Types/Term.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + typealias Name = String 6 + 7 + indirect enum Term: Sendable { 8 + case local(index: Int) 9 + case global(name: Name) 10 + case fun(dom: AsyncThunk<Type_>, boundName: String?, body: Term) 11 + case record(boundName: String?, fields: FieldDict<FieldImpl>) 12 + case cut(term: Term, frame: Frame) 13 + } 14 + 15 + extension Term { 16 + indirect enum Type_: Sendable { 17 + case funType(dom: Type_, boundName: String?, fam: Type_) 18 + case recordType(boundName: String?, fields: FieldDict<FieldSpec>) 19 + } 20 + 21 + indirect enum Frame { 22 + case app(arg: Term) 23 + case proj(fieldName: String) 24 + } 25 + 26 + struct FieldSpec { 27 + let type: Type_ 28 + let manifest: Term? 29 + } 30 + 31 + struct FieldImpl { 32 + let type: Type_ 33 + let value: Term 34 + } 35 + }
+59
Sources/PterodactylKernel/Core Types/Value.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + struct Closure<Body>{ 6 + let evaluator: Evaluator 7 + let body: Body 8 + } 9 + 10 + extension Closure: Sendable where Body: Sendable {} 11 + 12 + indirect enum Value: Sendable { 13 + case shift(neutral: Neutral) 14 + case fun(dom: AsyncThunk<Type_>, boundName: String?, closure: Closure<Term>) 15 + case record(boundName: String?, fields: FieldDict<FieldImpl>) 16 + } 17 + 18 + extension Value { 19 + indirect enum Type_: Sendable { 20 + case funType(dom: Type_, boundName: String?, fam: Closure<Term.Type_>) 21 + case recordType(boundName: String?, fields: FieldDict<FieldSpec>) 22 + } 23 + 24 + struct FieldSpec { 25 + let type: Closure<Term.Type_> 26 + let manifest: Closure<Term>? 27 + } 28 + 29 + struct FieldImpl { 30 + let type: Closure<Term.Type_> 31 + let value: Closure<Term> 32 + } 33 + 34 + indirect enum Frame { 35 + case app(arg: Value) 36 + case proj(fieldName: String) 37 + } 38 + 39 + typealias Spine = [Frame] 40 + 41 + enum Head { 42 + case local(level: Int) 43 + case global(name: Name) 44 + } 45 + 46 + struct Neutral { 47 + let head: Head 48 + let spine: Spine 49 + let boundary: AsyncThunk<Boundary> 50 + } 51 + 52 + struct Boundary { 53 + let type: Type_ 54 + let value: Value? 55 + } 56 + } 57 + 58 + 59 +
+85
Sources/PterodactylKernel/Evaluator.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + struct Evaluator { 6 + let globals: [Name: Value] 7 + let locals: [Value] 8 + 9 + func extendedBy(value: Value) -> Self { 10 + Self(globals: globals, locals: CollectionOfOne(value) + locals) 11 + } 12 + 13 + func close<Body>(body: Body) -> Closure<Body> { 14 + Closure(evaluator: self, body: body) 15 + } 16 + 17 + func close(fieldSpec: Term.FieldSpec) -> Value.FieldSpec { 18 + Value.FieldSpec( 19 + type: close(body: fieldSpec.type), 20 + manifest: fieldSpec.manifest.map(close(body:)) 21 + ) 22 + } 23 + 24 + func close(fieldImpl: Term.FieldImpl) -> Value.FieldImpl { 25 + Value.FieldImpl( 26 + type: close(body: fieldImpl.type), 27 + value: close(body: fieldImpl.value) 28 + ) 29 + } 30 + 31 + func evaluate(frame: Term.Frame) -> Value.Frame { 32 + switch frame { 33 + case let .app(arg: arg): .app(arg: evaluate(term: arg)) 34 + case let .proj(fieldName: fieldName): .proj(fieldName: fieldName) 35 + } 36 + } 37 + 38 + func evaluate(term: Term) -> Value { 39 + switch term { 40 + case let .local(index: index): 41 + return locals[index] 42 + case let .global(name: name): 43 + return globals[name]! 44 + case let .cut(term: term, frame: frame): 45 + return evaluate(term: term) 46 + .plug(frame: evaluate(frame: frame)) 47 + case let .fun(dom: dom, boundName: boundName, body: body): 48 + return .fun( 49 + dom: AsyncThunk { await evaluate(type: dom.value()) }, 50 + boundName: boundName, 51 + closure: close(body: body) 52 + ) 53 + case let .record(boundName: boundName, fields: fields): 54 + return .record( 55 + boundName: boundName, 56 + fields: fields.map(close(fieldImpl:)) 57 + ) 58 + } 59 + } 60 + 61 + func evaluate(type: Term.Type_) -> Value.Type_ { 62 + switch type { 63 + case let .funType(dom: dom, boundName: boundName, fam: fam): 64 + .funType( 65 + dom: evaluate(type: dom), 66 + boundName: boundName, 67 + fam: close(body: fam) 68 + ) 69 + case let .recordType(boundName: boundName, fields: fields): 70 + .recordType(boundName: boundName, fields: fields.map(close(fieldSpec:))) 71 + } 72 + } 73 + } 74 + 75 + extension Closure where Body == Term { 76 + func instantiate(with value: Value) -> Value { 77 + evaluator.extendedBy(value: value).evaluate(term: body) 78 + } 79 + } 80 + 81 + extension Closure where Body == Term.Type_ { 82 + func instantiate(with value: Value) -> Value.Type_ { 83 + evaluator.extendedBy(value: value).evaluate(type: body) 84 + } 85 + }
+67
Sources/PterodactylKernel/Plug.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + protocol Plug { 6 + func plug(frame: Value.Frame) -> Self 7 + } 8 + 9 + 10 + extension Plug { 11 + func plug(spine: Value.Spine) -> Self { 12 + spine.reduce(self) { partialResult, frame in 13 + partialResult.plug(frame: frame) 14 + } 15 + } 16 + } 17 + 18 + extension Value: Plug { 19 + func plug(frame: Frame) -> Self { 20 + switch self { 21 + case let .fun(_, _, closure: closure): 22 + guard case let .app(arg: arg) = frame else { fatalError() } 23 + return closure.instantiate(with: arg) 24 + case let .record(_, fields: fields): 25 + guard case let .proj(fieldName) = frame else { fatalError() } 26 + guard let impl = fields[fieldName] else { fatalError() } 27 + return impl.value.instantiate(with: self) 28 + case let .shift(neutral: neutral): 29 + return .shift(neutral: neutral.plug(frame: frame)) 30 + } 31 + } 32 + } 33 + 34 + extension Value.Neutral: Plug { 35 + // Not async now, but might need to be later. 36 + func plug(boundary: Value.Boundary, frame: Value.Frame) async -> Value.Boundary { 37 + switch boundary.type { 38 + case let .funType(_, _, fam: fam): 39 + guard case let .app(arg: arg) = frame else { 40 + fatalError("Attempted to plug element of function type into invalid frame") 41 + } 42 + let fibre = fam.instantiate(with: arg) 43 + return Value.Boundary(type: fibre, value: boundary.value?.plug(frame: frame)) 44 + 45 + case let .recordType(_, fields: fields): 46 + guard case let .proj(fieldName) = frame else { 47 + fatalError("Attempted to plug element of record type into invalid frame") 48 + } 49 + guard let field = fields[fieldName] else { 50 + fatalError("Attempted to project invalid field from element of record type") 51 + } 52 + let fieldTypeValue = field.type.instantiate(with: .shift(neutral: self)) 53 + let value = boundary.value?.plug(frame: frame) ?? field.manifest.map { manifest in 54 + manifest.instantiate(with: .shift(neutral: self)) 55 + } 56 + return Value.Boundary(type: fieldTypeValue, value: value) 57 + } 58 + } 59 + 60 + func plug(frame: Value.Frame) -> Self { 61 + Self( 62 + head: head, 63 + spine: CollectionOfOne(frame) + spine, 64 + boundary: AsyncThunk { await plug(boundary: boundary.value(), frame: frame) } 65 + ) 66 + } 67 + }
+3
Sources/PterodactylKernel/PterodactylKernel.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0
+133
Sources/PterodactylKernel/Quotation.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + import Foundation 6 + 7 + struct Quotation { 8 + let depth: Int 9 + var next: Self { 10 + Quotation(depth: depth + 1) 11 + } 12 + 13 + func quote(type: Value.Type_) -> Term.Type_ { 14 + switch type { 15 + case let .funType(dom: dom, boundName: boundName, fam: fam): 16 + return .funType( 17 + dom: quote(type: dom), 18 + boundName: boundName, 19 + fam: quote(dom: AsyncThunk(value: dom), family: fam) 20 + ) 21 + 22 + case let .recordType(boundName: boundName, fields: fields): 23 + var fieldSpecs: [(String, Value.FieldSpec)] = [] 24 + var quotedFieldSpecs: [(String, Term.FieldSpec)] = [] 25 + 26 + for (key, fieldSpec) in fields.elements { 27 + let dom: AsyncThunk<Value.Type_> = AsyncThunk(value: .recordType(boundName: boundName, fields: FieldDict(fieldSpecs))) 28 + let quotedFieldSpec = quote(dom: dom, fieldSpec: fieldSpec) 29 + fieldSpecs.append((key, fieldSpec)) 30 + quotedFieldSpecs.append((key, quotedFieldSpec)) 31 + } 32 + 33 + return .recordType( 34 + boundName: boundName, 35 + fields: FieldDict(quotedFieldSpecs) 36 + ) 37 + } 38 + } 39 + 40 + func quote(dom: AsyncThunk<Value.Type_>, fieldSpec: Value.FieldSpec) -> Term.FieldSpec { 41 + return Term.FieldSpec( 42 + type: quote(dom: dom, family: fieldSpec.type), 43 + manifest: fieldSpec.manifest.map { quote(dom: dom, closure: $0) } 44 + ) 45 + } 46 + 47 + func quote(dom: AsyncThunk<Value.Type_>, fieldImpl: Value.FieldImpl) -> Term.FieldImpl { 48 + return Term.FieldImpl( 49 + type: quote(dom: dom, family: fieldImpl.type), 50 + value: quote(dom: dom, closure: fieldImpl.value) 51 + ) 52 + } 53 + 54 + func quote(value: Value) -> Term { 55 + switch value { 56 + case let .shift(neutral: neutral): 57 + return quote(neutral: neutral) 58 + 59 + case let .fun(dom: dom, boundName: boundName, closure: closure): 60 + return .fun( 61 + dom: AsyncThunk { await quote(type: dom.value()) }, 62 + boundName: boundName, 63 + body: quote(dom: dom, closure: closure) 64 + ) 65 + 66 + case let .record(boundName: boundName, fields: fields): 67 + var fieldSpecs: [(String, Value.FieldSpec)] = [] 68 + var quotedFields: [(String, Term.FieldImpl)] = [] 69 + 70 + for (key, fieldImpl) in fields.elements { 71 + let fieldSpec = Value.FieldSpec(type: fieldImpl.type, manifest: fieldImpl.value) 72 + let quotedFieldImpl = quote( 73 + dom: AsyncThunk(value: .recordType(boundName: boundName, fields: FieldDict(fieldSpecs))), 74 + fieldImpl: fieldImpl 75 + ) 76 + 77 + fieldSpecs.append((key, fieldSpec)) 78 + quotedFields.append((key, quotedFieldImpl)) 79 + } 80 + 81 + return .record(boundName: boundName, fields: FieldDict(quotedFields)) 82 + } 83 + } 84 + 85 + func fresh(type: AsyncThunk<Value.Type_>) -> Value { 86 + let boundary: AsyncThunk<Value.Boundary> = AsyncThunk { 87 + await Value.Boundary(type: type.value(), value: nil) 88 + } 89 + 90 + return Value.shift( 91 + neutral: Value.Neutral( 92 + head: .local(level: depth), 93 + spine: [], 94 + boundary: boundary 95 + ) 96 + ) 97 + } 98 + 99 + func quote(dom: AsyncThunk<Value.Type_>, closure: Closure<Term>) -> Term { 100 + let x = fresh(type: dom) 101 + let value = closure.instantiate(with: x) 102 + return next.quote(value: value) 103 + } 104 + 105 + func quote(dom: AsyncThunk<Value.Type_>, family: Closure<Term.Type_>) -> Term.Type_ { 106 + let x = fresh(type: dom) 107 + let value = family.instantiate(with: x) 108 + return next.quote(type: value) 109 + } 110 + 111 + private func quote(head: Value.Head) -> Term { 112 + switch head { 113 + case let .local(level: level): .local(index: depth - level - 1) 114 + case let .global(name: name): .global(name: name) 115 + } 116 + } 117 + 118 + private func quote(frame: Value.Frame) -> Term.Frame { 119 + switch frame { 120 + case let .app(arg: arg): 121 + return .app(arg: quote(value: arg)) 122 + case let .proj(fieldName: fieldName): 123 + return .proj(fieldName: fieldName) 124 + } 125 + } 126 + 127 + private func quote(neutral: Value.Neutral) -> Term { 128 + let headTerm = quote(head: neutral.head) 129 + return neutral.spine.reduce(headTerm) { term, frame in 130 + .cut(term: term, frame: quote(frame: frame)) 131 + } 132 + } 133 + }
+12
Sources/PterodactylKernel/Whnf.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + extension Value { 6 + func whnf() async -> Value { 7 + switch self { 8 + case .fun, .record : self 9 + case let .shift(neutral: neutral): await neutral.boundary.value().value ?? self 10 + } 11 + } 12 + }
+11
Tests/PterodactylKernelTests/PterodactylKernelTests.swift
··· 1 + // SPDX-FileCopyrightText: 2025 The Project Pterodactyl Developers 2 + // 3 + // SPDX-License-Identifier: MPL-2.0 4 + 5 + import Testing 6 + 7 + @testable import PterodactylKernel 8 + 9 + @Test func example() async throws { 10 + // Write your test here and use APIs like `#expect(...)` to check expected conditions. 11 + }