├── .gitignore ├── LICENSE ├── Setup.hs ├── changelog.md ├── readme.md ├── resin.cabal └── src ├── Resin.hs └── Resin ├── Binders ├── Tree.hs └── Tree │ └── Internal.hs ├── Calculus └── Derivatives.hs └── Environment └── Class.hs /.gitignore: -------------------------------------------------------------------------------- 1 | cabal.project.local 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Carter Tazio Schonwald 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the 14 | distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | 2 | # Versions 0.1.0.0 - 0.1.0.2 3 | initial release(s) with only the private proof rep for tree paths 4 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Resin : High performance Planar (2D) Variable binders 2 | 3 | Resin is an experiment in variable binder design inspired by binder libraries 4 | such as Bound and UnBound (no relation), with the goal being to provide 5 | high performance and excellent abstraction on as large a space of syntaxes as 6 | is feasible. 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resin.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.2 2 | -- Initial resin.cabal generated by cabal init. For further documentation, 3 | -- see http://haskell.org/cabal/users-guide/ 4 | 5 | -- The name of the package. 6 | name: resin 7 | 8 | -- The package version. See the Haskell package versioning policy (PVP) 9 | -- for standards guiding when and how versions should be incremented. 10 | -- http://www.haskell.org/haskellwiki/Package_versioning_policy 11 | -- PVP summary: +-+------- breaking API changes 12 | -- | | +----- non-breaking API additions 13 | -- | | | +--- code changes with no API change 14 | version: 0.2.0.3 15 | 16 | -- A short (one-line) description of the package. 17 | synopsis: High performance variable binders 18 | 19 | -- A longer description of the package. 20 | description: High Performance Variable Binders library 21 | 22 | -- URL for the project homepage or repository. 23 | homepage: http://github.com/cartazio/resin 24 | 25 | 26 | -- The license under which the package is released. 27 | license: BSD-2-Clause 28 | 29 | -- The file containing the license text. 30 | license-file: LICENSE 31 | 32 | -- The package author(s). 33 | author: Carter Tazio Schonwald 34 | 35 | -- An email address to which users can send suggestions, bug reports, and 36 | -- patches. 37 | maintainer: carter at wellposed dot com 38 | 39 | -- A copyright notice. 40 | -- copyright: 41 | 42 | category: Language 43 | 44 | build-type: Simple 45 | 46 | 47 | 48 | -- Extra files to be distributed with the package, such as examples or a 49 | -- README. 50 | extra-source-files: readme.md 51 | changelog.md 52 | 53 | 54 | 55 | 56 | 57 | source-repository head 58 | type: git 59 | location: https://github.com/cartazio/resin.git 60 | 61 | library 62 | -- Modules exported by the library. 63 | exposed-modules: 64 | -- Resin 65 | 66 | Resin.Binders.Tree 67 | ,Resin.Binders.Tree.Internal 68 | 69 | -- ,Resin.Calculus.Derivatives 70 | 71 | -- ,Resin.Environment.Class 72 | 73 | -- Modules included in this library but not exported. 74 | -- other-modules: 75 | 76 | -- LANGUAGE extensions used by modules in this package. 77 | -- other-extensions: 78 | 79 | -- Other library packages from which modules are imported. 80 | build-depends: base >= 4.8 && < 5 81 | ,ghc-prim 82 | -- >= 0.4 && < 0.6 83 | ,semigroupoids >= 5.0 && < 5.4 84 | ,ralist == 0.2.* 85 | 86 | 87 | -- Directories containing source files. 88 | hs-source-dirs: src 89 | 90 | ghc-options: -Wall 91 | 92 | if impl(ghc >= 8.0) && impl(ghc < 8.2) 93 | ghc-options: -Wno-redundant-constraints 94 | 95 | -- Base language which the package is written in. 96 | default-language: Haskell2010 97 | 98 | -------------------------------------------------------------------------------- /src/Resin.hs: -------------------------------------------------------------------------------- 1 | module Resin where 2 | 3 | -------------------------------------------------------------------------------- /src/Resin/Binders/Tree.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE Trustworthy #-} 2 | module Resin.Binders.Tree( 3 | -- | the safe subset of the api... I think 4 | IxEq(..) 5 | ,Inject(InjectRefl) 6 | ,Extract -- Extract is just a newtype wrapper .. for now 7 | ,TreeEq(..) 8 | ,treeElimination 9 | ,rightExtendInject 10 | ,leftExtendExtract 11 | ,jumpDepthInject -- not sure if this operation is safe 12 | ,jumpDepthExtract -- not sure if thats safe too 13 | ) 14 | where 15 | import Resin.Binders.Tree.Internal 16 | 17 | -------------------------------------------------------------------------------- /src/Resin/Binders/Tree/Internal.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleContexts,FlexibleInstances,GADTs,DataKinds, PolyKinds, KindSignatures #-} 2 | {-# LANGUAGE DeriveDataTypeable #-} 3 | {-# LANGUAGE ScopedTypeVariables #-} 4 | {-# LANGUAGE BangPatterns #-} 5 | {-# LANGUAGE TypeOperators #-} 6 | 7 | module Resin.Binders.Tree.Internal( 8 | -- | the safe subset of the api... I think 9 | IxEq(..) 10 | ,Inject(..) 11 | ,Extract(..) -- Extract is just a newtype wrapper .. for now 12 | ,TreeEq(..) 13 | ,treeElimination 14 | ,rightExtendInject 15 | ,leftExtendExtract 16 | ,jumpDepthInject -- not sure if this operation is safe 17 | ,jumpDepthExtract -- not sure if thats safe too 18 | ) where 19 | import Numeric.Natural 20 | import Data.Semigroupoid 21 | --import Data.Coerce 22 | import Unsafe.Coerce (unsafeCoerce) 23 | import Data.Type.Equality 24 | --import qualified Data.Semigroupoid.Dual as DL 25 | 26 | 27 | 28 | {- 29 | This module models binders which respect scope having a tree shaped topology 30 | or at least it models some ideas about (finite?) paths on (finite??!) trees 31 | 32 | -} 33 | 34 | 35 | data IxEq :: (k -> * ) -> k -> k -> * where 36 | PolyRefl :: IxEq f i i 37 | MonoRefl :: forall f i . f i -> IxEq f i i 38 | 39 | --testIxEquality :: TestEquality f => IxEq f a b -> IxEq f b c -> 40 | 41 | instance TestEquality f => TestEquality (IxEq f i) where 42 | testEquality (MonoRefl f1) (MonoRefl f2) = testEquality f1 f2 43 | testEquality (PolyRefl )(MonoRefl _f2) = Just Refl 44 | testEquality (MonoRefl _f1) (PolyRefl ) = Just Refl 45 | testEquality (PolyRefl ) (PolyRefl ) = Just Refl 46 | 47 | {- | `Inject` is about 48 | 49 | -} 50 | data Inject :: (k -> * ) -> k -> k -> * where 51 | InjectRefl :: forall f a b . IxEq f a b-> Inject f a b 52 | --MonoId :: forall f i . (f i) -> Inject f i i 53 | -- should MonoId be strict in its argument? 54 | CompactCompose :: forall f i j . (IxEq f i i) -> (IxEq f j j ) -> Natural -> Inject f i j 55 | -- i is origin/root 56 | -- j is leaf 57 | -- compact compose is unsafe for users, but should be exposed in a .Internal 58 | -- module 59 | 60 | rightExtendInject :: Inject p a b -> p c -> Inject p a c 61 | rightExtendInject (InjectRefl PolyRefl) rP = CompactCompose PolyRefl (MonoRefl rP) 1 62 | rightExtendInject (InjectRefl (MonoRefl f)) rP = CompactCompose (MonoRefl f) (MonoRefl rP) 1 63 | rightExtendInject (CompactCompose pa _pb n) rP = CompactCompose pa (MonoRefl rP) (n+1 ) 64 | 65 | leftExtendExtract :: p a -> Extract p b c -> Extract p a c 66 | leftExtendExtract p (Dual inj) = Dual (rightExtendInject inj p) 67 | 68 | 69 | jumpDepthInject :: Natural -> p c -> Inject p a b -> Inject p a c 70 | jumpDepthInject plus pc (InjectRefl PolyRefl) = CompactCompose PolyRefl (MonoRefl pc) (1 + plus) 71 | jumpDepthInject plus pc (InjectRefl (MonoRefl pa)) = CompactCompose (MonoRefl pa) (MonoRefl pc) (1 + plus) 72 | jumpDepthInject plus pc (CompactCompose pa _pb n) = CompactCompose pa (MonoRefl pc) (n + plus + 1 ) 73 | 74 | jumpDepthExtract :: Natural -> Extract p b c -> p a -> Extract p a c 75 | jumpDepthExtract plus (Dual cc) pc = Dual (jumpDepthInject plus pc cc) 76 | 77 | instance Semigroupoid (Inject f) where 78 | --PolyId `o` PolyId = PolyId 79 | (InjectRefl (MonoRefl _p)) `o` (!f) = f 80 | (InjectRefl (PolyRefl)) `o` (!f) = f 81 | (CompactCompose in1 out1 size) `o` (InjectRefl (PolyRefl)) = CompactCompose in1 out1 size 82 | (CompactCompose in1 out1 size) `o` (InjectRefl (MonoRefl !_p)) = CompactCompose in1 out1 size 83 | (CompactCompose _cmiddle2 cout sizeleft) 84 | `o` (CompactCompose cin _cmiddle1 sizeright) = CompactCompose cin cout (sizeright + sizeleft) 85 | --- TODO is this case too lazy? 86 | 87 | -- extract is the dual of Inject 88 | -- aka Data.Semigroupoid.Dual is nearly the exact same type :) 89 | newtype Extract :: (k -> * ) -> k -> k -> * where 90 | Dual :: ((Inject f) b a ) -> Extract f a b 91 | -- not sure if this is the right design vs 92 | -- :: Inject f b a -> Extract f a b --- (which has more explicit duality and less newtypery) 93 | 94 | 95 | instance Semigroupoid (Extract f) where 96 | o = \ (Dual l) (Dual r) -> Dual $ r `o` l 97 | 98 | 99 | data TreeEq :: (k -> * ) -> k -> k -> * where 100 | TreeInject :: Inject f a b -> TreeEq f a b 101 | TreeExtract :: Extract f a b -> TreeEq f a b 102 | TreeRefl :: TreeEq f c c 103 | 104 | 105 | --- this might limit a,c to being kind (or sort?) * / Type for now, but thats OK ?? 106 | treeElimination :: TestEquality f => Inject f a b -> Extract f b c-> (TreeEq f a c) 107 | treeElimination (InjectRefl PolyRefl) (Dual (InjectRefl PolyRefl)) = TreeRefl 108 | treeElimination (InjectRefl (MonoRefl _p1)) (Dual (InjectRefl PolyRefl)) = TreeRefl 109 | treeElimination (InjectRefl PolyRefl) (Dual (InjectRefl (MonoRefl _p2))) = TreeRefl 110 | treeElimination (InjectRefl (MonoRefl _p1)) (Dual (InjectRefl(MonoRefl _p2))) = TreeRefl 111 | treeElimination (CompactCompose fa _fb1 n1) (Dual (CompactCompose fc _fb2 n2)) = 112 | case (compare n1 n2, max n1 n2 - min n1 n2) of 113 | (EQ, _ )-> (unsafeCoerce TreeRefl) :: TreeEq f a c 114 | --- if the path is zero length they must be equal! 115 | --- AUDIT MEEEE 116 | (GT, m )-> TreeInject (CompactCompose fa fc m) 117 | (LT, m ) -> TreeExtract (Dual (CompactCompose fc fa m)) 118 | treeElimination (InjectRefl p@(PolyRefl)) 119 | d@(Dual (CompactCompose _fc _fb _n)) = treeElimination (CompactCompose p p 0) d 120 | treeElimination (InjectRefl p@(MonoRefl _)) 121 | d@(Dual (CompactCompose _fc _fb _n)) = treeElimination (CompactCompose p p 0) d 122 | treeElimination d@( CompactCompose _fc _fb _n) 123 | (Dual (InjectRefl p@(PolyRefl))) = treeElimination d (Dual (CompactCompose p p 0)) 124 | treeElimination d@(CompactCompose _fc _fb _n) 125 | (Dual (InjectRefl p@(MonoRefl _))) = treeElimination d (Dual (CompactCompose p p 0)) 126 | 127 | -------------------------------------------------------------------------------- /src/Resin/Calculus/Derivatives.hs: -------------------------------------------------------------------------------- 1 | module Resin.Calculus.Derivatives where 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Resin/Environment/Class.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleContexts,FlexibleInstances,GADTs,DataKinds#-} 2 | {-# LANGUAGE DeriveDataTypeable #-} 3 | {-# LANGUAGE ScopedTypeVariables #-} 4 | 5 | {- | This Module essentially stubs out the subset 6 | of Random Access Stack operations we need for efficient substitution environments 7 | 8 | -} 9 | module Resin.Environment.Class ( 10 | ) where 11 | --------------------------------------------------------------------------------