@@ -1,15 +1,31 @@
1{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
1{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
3−module Nock (tar, hax, fas, cell, atom, Annotation (..), Noun) where
3+module Nock (tar, cell, atom, Annotation (..), Noun, RawNoun (..)) where
5−import Data.Bits
5+import Data.Hashable
6−import Data.Functor ((<&>))
6+import GHC.Generics (Generic)
7−import Effectful
7+import Numeric.Natural
8−import Effectful.State.Static.Local qualified as SEL
8+import Test.QuickCheck.Arbitrary.Generic
10−import GHC.Num
10+data Annotation = Annotation
11−import GHC.Num.BigNat (bigNatAddWord#, bigNatFromWord2#)
11+ { hash :: Int
12−import Nock.Types
12+ }
13+ deriving stock (Show)
18+atom :: Natural -> Noun
19+atom nat = Atom nat Annotation {hash = hash nat}
21+cell :: Noun -> Noun -> Noun
27+ { hash = hash ((annotation lhs).hash, (annotation rhs).hash)
14sig :: Noun
30sig :: Noun
15sig = atom 0
31sig = atom 0
@@ -17,119 +33,83 @@ sig = atom 0
17one :: Noun
33one :: Noun
18one = atom 1
34one = atom 1
20−two :: Noun
36+annotation :: RawNoun ann -> ann
21−two = atom 2
37+annotation (Atom _ ann) = ann
38+annotation (Cell _ _ ann) = ann
23−three :: Noun
40+data RawNoun ann
24−three = atom 3
41+ = Atom !Natural ann
42+ | Cell (RawNoun ann) (RawNoun ann) ann
43+ deriving stock (Generic, Show)
26−four :: Noun
45+instance Eq (RawNoun ann) where
27−four = atom 4
46+ (Atom lhs _) == (Atom rhs _) = lhs == rhs
47+ (Cell lhslhs lhsrhs _) == (Cell rhslhs rhsrhs _) = lhslhs == rhslhs && lhsrhs == rhsrhs
29−twoThree :: Noun
50+hashEq :: Noun -> Noun -> Bool
30−twoThree = cell two three
51+hashEq (Atom lhsNat lhsAnn) (Atom rhsNat rhsAnn) =
52+ lhsAnn.hash == rhsAnn.hash && lhsNat == rhsNat
53+hashEq (Cell lhslhs lhsrhs lhsAnn) (Cell rhslhs rhsrhs rhsAnn) =
54+ lhsAnn.hash == rhsAnn.hash && hashEq lhslhs rhslhs && hashEq lhsrhs rhsrhs
32−sigOne :: Noun
57+type Noun = RawNoun Annotation
35wut :: Noun -> Noun
59wut :: Noun -> Noun
36wut Cell {} = sig
60wut Cell {} = sig
37wut Atom {} = one
61wut Atom {} = one
39lus :: Noun -> Noun
63lus :: Noun -> Noun
40−lus ~(Atom nat _) = atom $ case nat of
64+lus ~(Atom nat _) = atom (nat + 1)
41− (NS n) -> case addWordC# n 1## of
43− (# l, c #) -> NB (bigNatFromWord2# (int2Word# c) l)
44− (NB n) -> NB (bigNatAddWord# n 1##)
46−tis :: Noun -> Noun -> Eff es Noun
66+tis :: Noun -> Noun
47−tis lhs rhs = pure $ if lhs == rhs then sig else one
67+tis ~(Cell lhs rhs _) = if hashEq lhs rhs then sig else one
49−fas# :: Word# -> Noun -> Noun
69+fas :: Noun -> Noun
50−fas# lhs rhs =
70+fas ~(Cell ~(Atom lhs _) rhs _) =
51 case lhs of
71 case lhs of
52− 1## -> rhs
72+ 1 -> rhs
53− 2## -> case rhs of
73+ 2 -> case rhs of
54 ~(Cell lhs' _ _) -> lhs'
74 ~(Cell lhs' _ _) -> lhs'
55− 3## -> case rhs of
75+ 3 -> case rhs of
56 ~(Cell _ rhs' _) -> rhs'
76 ~(Cell _ rhs' _) -> rhs'
58− let rest = fas# (uncheckedShiftRL# n 1#) rhs
78+ | n > 0 ->
59− in case and# 1## n of
79+ let (d, m) = divMod n 2
63−fas :: Natural -> Noun -> Noun
64−fas (NS w) rhs = fas# w rhs
66− let rest = fas (unsafeShiftR n 1) rhs
71−hax# :: Word# -> Noun -> Noun -> Noun
74− let a = uncheckedShiftRL# n 1#
75− in case and# n 1## of
76− 1## -> hax# a (cell (fas# (n `xor#` 1##) c) b) c
77− _ -> hax# a (cell b (fas# (n `or#` 1##) c)) c
79−hax :: Natural -> Noun -> Noun -> Noun
80−hax (NS n) b c = hax# n b c
82− let a = unsafeShiftR n 1
83− in if testBit n 0
80+ in if m == 0
84− then hax a (cell (fas (n - 1) c) b) c
81+ then fas (cell (atom 2) (fas (cell (atom d) rhs)))
85− else hax a (cell b (fas (n + 1) c)) c
82+ else fas (cell (atom 3) (fas (cell (atom d) rhs)))
87−tar :: Noun -> Eff es Noun
88−tar ~(Cell subject ~(Cell a b _) _) = tar' a b subject
90−tar' :: Noun -> Noun -> Noun -> Eff es Noun
91−tar' b c subject = case b of
92− Cell x y _ -> case c of
93− ~(Cell l k _) -> cell <$> tar' x y subject <*> tar' l k subject
94− Atom (NB _) _ -> undefined
83+ _ -> undefined
86+hax ~(Cell ~(Atom n _) ~(Cell a b _) _) =
87+ let (d, m) = divMod n 2
95− Atom (NS n) _ -> case n of
88+ in case n of
96− 0## -> case c of
89+ 1 -> a
97− ~(Atom nat _) -> pure $ fas nat subject
90+ _ | m == 0 -> hax (cell (atom d) (cell (cell a (fas (cell (atom $ n + 1) b))) b))
98− 1## -> pure c
91+ _ -> hax (cell (atom d) (cell (cell (fas (cell (atom $ n + n) b)) a) b))
100− ~(Cell l k _) -> wut <$> tar' l k subject
93+tar :: Noun -> Noun
101− 4## -> case c of
94+tar ~(Cell a ~(Cell b c _) _) = case b of
102− ~(Cell l k _) -> lus <$> tar' l k subject
95+ Cell x y _ -> cell (tar (cell a (cell x y))) (tar (cell a c))
96+ Atom n _ -> case n of
99+ 3 -> wut $ tar $ cell a c
100+ 4 -> lus $ tar $ cell a c
103 _ -> case c of
101 _ -> case c of
104− ~(Cell x ~(Cell h j _) _) -> case n of
102+ ~(Cell x y _) -> case n of
105− 2## -> case x of
103+ 2 -> tar $ cell (tar $ cell a x) (tar $ cell a y)
106− ~(Cell l k _) ->
104+ 5 -> tis $ cell (tar $ cell a x) (tar $ cell a y)
107− tar' l k subject >>= \case
105+ 7 -> tar $ cell (tar $ cell a x) y
108− ~formula@(Cell battery ~(Cell sample _ _) _) ->
106+ 8 -> tar $ cell (cell (tar $ cell a x) a) y
109− -- if traceShowId battery == Nock.Jets.add
107+ 9 -> tar $ cell (tar $ cell a y) $ cell (atom 2) (cell (cell sig one) (cell sig x))
110− -- then error "Found it!"
108+ 6 -> case y of
111− tar' h j subject >>= \case
109+ ~(Cell l k _) -> tar $ cell a $ tar $ cell (cell l k) $ cell sig $ tar $ cell (cell (atom 2) (atom 3)) $ cell sig $ tar $ cell a (cell (atom 4) (cell (atom 4) x))
112− ~(Cell u v _) -> tar' u v formula
115− p <- tar' h j subject
116− q <- tar' l k subject
119− ~(Cell l k _) -> tar' l k subject >>= tar' h j
122− p <- tar' l k subject
123− tar' h j (cell p subject)
124− 9## -> tar' h j subject >>= tar' two (cell sigOne (cell sig x))
126− p <- tar' four (cell four x) subject
127− q <- tar' sig p twoThree
128− tar' sig q (cell h j) >>= \case
129− ~(Cell u v _) -> tar' u v subject
130− 10## -> case x of
110+ 10 -> case x of
131− ~(Cell ~(Atom b' _) ~(Cell u v _) _) -> hax b' <$> tar' u v subject <*> tar' h j subject
111+ ~(Cell l k _) -> hax $ cell l $ cell (tar (cell a k)) $ tar $ cell a y
132− 11## -> case x of
112+ 11 -> case c of
133− Cell _ ~(Cell u v _) _ -> tar' h j subject
113+ Cell l k _ -> tar $ cell (cell (tar $ cell a l) (tar $ cell a k)) $ cell sig (atom 3)
134− Atom _ _ -> tar' h j subject
114+ Atom l _ -> tar $ cell a y
135 _ -> undefined
115 _ -> undefined