-- Copyright (C) 2018 Zaoqi -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU Affero General Public License as published -- by the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Affero General Public License for more details. -- You should have received a copy of the GNU Affero General Public License -- along with this program. If not, see . module Lang.Lang(算, 空境) where import Lang.Value import Lang.Cast import Lang.Common import Mapping infixr 0 ? W誤 _ ? _ = Nothing _ ? x = x mkfM :: List String -> (List W物 -> Maybe W物) -> (List W物 -> W物) mkfM n f = \xs -> case f xs of Just x -> x Nothing -> 界誤 n xs class C建參 x where 建參 :: Nat -> x instance C建參 X形 where 建參 x = 建列 (map (\x -> 建名[show x]) [x,x-1..1]) instance C建參 W物 where 建參 x = 建列 (map (\x -> 建名[show x]) [x,x-1..1]) f :: List String -> Nat -> (List W物 -> W物) -> (M名物, W物) f n c x = (建名 n, 界機 (MkJJ界機物 n c x (建參 c) (首尾 (建界名 n) (建參 c)))) fM :: List String -> Nat -> (List W物 -> Maybe W物) -> (M名物, W物) fM n c x = f n c (mkfM n x) m :: List String -> Nat -> (Mapping M名物 W物 -> List W物 -> Maybe W物) -> (M名物, W物) m n c x = (建名 n, 引機 (界機 (MkJJ界機物 n ce f (建參 ce) (建列[建界名["算"], 未算, 建名[show ce]])))) where f :: (List W物 -> W物) f _a@(e : xs) = case (物To境 e >>= \e -> x e xs) of Just x -> x Nothing -> 界誤 n _a ce :: Nat ce = c+1 未算 :: W物 未算 = 建首尾 (引 用式名) (建首尾 (引 (建界名 n)) (連參 c)) 連參 :: Nat -> W物 連參 1 = 建首尾 (建名["1"]) (建界名["空"]) 連參 n = 建首尾 (建名[show n]) (連參 (n-1)) 建首尾 :: W物 -> W物 -> W物 建首尾 a d = 建列[建界名["首尾"], a, d] 引 :: W物 -> W物 引 x = 建式 (建界名["引"]) [x] 空境 :: Mapping M名物 W物 空境 = (listToMapping [ (fM["等","?"]2(\[x,y] -> x?y? Just (建陰陽 (x == y)))), (fM["首尾","?"]1(\[x] -> x? case x of W首尾 _ _ -> Just 陽 _ -> Just 陰)), (f["首尾"]2(\[x,y] -> 首尾 x y)), (fM["首尾","首"]1(\[x] -> x? case x of W首尾 x _ -> Just x _ -> Nothing)), (fM["首尾","尾"]1(\[x] -> x? case x of W首尾 _ x -> Just x _ -> Nothing)), (fM["空","?"]1(\[x] -> x? case x of W空 -> Just 陽 _ -> Just 陰)), (建名["列"], 機 MappingNil (建名 ["1"]) (建名 ["1"])), (fM["字","?"]1(\[x] -> x? case x of W字 _ -> Just 陽 _ -> Just 陰)), (fM["名","?"]1(\[x] -> x? case x of W名 _ -> Just 陽 _ -> Just 陰)), (fM["列","→","名"]1(\[x] -> x? 名 <$> 物To列 x)), (fM["名","→","列"]1(\[x] -> x? case x of W名 x -> Just (列To物 x) _ -> Nothing)), (fM["映","?"]1(\[x] -> x? case x of W映 _ -> Just 陽 _ -> Just 陰)), (建名["映","空"], W映 (Y境 MappingNil)), (fM["映","改"]3(\[h, k, v] -> case h of W映 h -> Just $ case h of Y物映 h -> W映 (Y物映 (mappingSet h k v)) Y境 h -> W映 $ case k of W名 k -> Y境 (mappingSet h (名 k) v) _ -> Y物映 (mappingSet (境ToMapping h) k v) _ -> Nothing)), (fM["映","取"]3(\[h, k] -> case h of W映 h -> case h of Y物映 h -> mappingRef h k Y境 h -> case k of W名 k -> mappingRef h (名 k) _ -> Nothing _ -> Nothing)), (fM["映","含","?"]2(\[h, k] -> case h of W映 h -> Just $ case h of Y物映 h -> 建陰陽 (mappingHas h k) Y境 h -> case k of W名 k -> 建陰陽 (mappingHas h (名 k)) _ -> 陰 _ -> Nothing)), (fM["映","删"]2(\[hw, k] -> case hw of W映 h -> case h of Y物映 h -> case mappingRemove h k of Just x -> Just $ W映 (Y物映 x) Nothing -> Nothing Y境 h -> case k of W名 kl -> case mappingRemove h (名 kl) of Just x -> Just $ W映 (Y境 x) Nothing -> Nothing _ -> Nothing _ -> Nothing)), (fM["映","→","列"]1(\[h] -> h? case h of W映 h -> Just $ case h of Y物映 h -> 建列 (map (\(a, d) -> 首尾 a d) (mappingToList h)) Y境 h -> 建列 (map (\(M名 a, d) -> 首尾 (名 a) d) (mappingToList h)) _ -> Nothing)), (fM["機","?"]1(\[x] -> x? case x of W機 _ _ _ -> Just 陽 W界機 _ -> Just 陽 _ -> Just 陰)), (fM["機"]2(\[x, y] -> x? fmap (\x -> 機 MappingNil x y) (物To形 x))), (fM["用"]2(\[f, xs] -> f?xs? 用 <$> 物To機物 f <*> 物ToList xs)), (fM["機","形"]1(\[x] -> x? case x of W機 _ x _ -> Just (形To物 x) W界機 (MkJJ界機物 _ _ _ x _) -> Just (形To物 x) _ -> Nothing)), (fM["機","物"]1(\[x] -> 機Get物 x)), (m["入"]2(\e [x, w] -> 物To形 x >>= \x -> Just (機 e x w))), (建名["陰"], 陰), (建名["陽"], 陽), (fM["若"]3(\[b, x, y] -> b? case b of W陽 -> Just x _ -> Just y)), (fM["引機","?"]1(\[x] -> x? case x of W引機 _ -> Just 陽 _ -> Just 陰)), (fM["引機"]1(\[x] -> x? W引機 <$> 物To機物 x)), (fM["引機","反"]1(\[x] -> x? case x of W引機 x -> Just (機物To物 x) _ -> Nothing)), (fM["譯機","?"]1(\[x] -> x? case x of W譯機 _ -> Just 陽 _ -> Just 陰)), (fM["譯機"]1(\[x] -> x? W譯機 <$> 物To機物 x)), (fM["譯機","反"]1(\[x] -> x? case x of W譯機 x -> Just (機物To物 x) _ -> Nothing)), (建名["引"], 引機 (機 MappingNil (建列[建名 ["e"], 建名["x"]]) (建名["x"]))), (f["誤","?"]1(\[x] -> case x of W誤 _ -> 陽 _ -> 陰)), (f["誤"]1(\[x] -> W誤 x)), (fM["誤","反"]1(\[x] -> case x of W誤 x -> Just x _ -> Nothing)), (fM["算"]2(\[x,e] -> x?e? 算 x <$> 物To境 e)), (m["境","名今"]2(\e [n, x] -> 物To名 n >>= \n -> return (算 x (mappingSet e n (境To物 e))))), (m["境","改"]2(\_ [e, x] -> 算 x <$> 物To境 e)), (建名["境","空"], 境To物 空境), (m["命名"]2(\e [n, body] -> do n <- 物ToList n n <- mapM (\x -> do { W首尾 (W名 m) (W首尾 v W空) <- return x ; return (名 m, v) }) n return $ let e' = mappingAppendList e n' n' = map (\(m, x) -> (m, 算 x e')) n in 算 body e')), (fM["構","?"]1(\[x] -> x? case x of W構 _ _ -> Just 陽 _ -> Just 陰)), (fM["構"]2(\[n,xs] -> 物To列 xs >>= \xs -> case n of W名 x -> Just (構 (名 x) xs) _ -> Nothing)), (fM["構","名"]1(\[x] -> x? case x of W構 (M名 x) _ -> Just (名 x) _ -> Nothing)), (fM["構","列"]1(\[x] -> x? case x of W構 _ xs -> Just (列To物 xs) _ -> Nothing)), (fM["取","未算"]1(\[x] -> x? case x of W名 x -> error "WIP" _ -> Nothing)), (建名["取"], W機 MappingNil (建列[建名["x"]]) (建列[建界名["算"], 建列[建界名["取","未算"], 建名["x"]], 建界名["境","空"]])), (fM["界","含","?"]1(\[x] -> x? case x of W名 x -> case x of _ -> Just 陰 _ -> Nothing)), (fM["界","取"]1(\[x] -> Nothing)) ]) 機Get物 :: W物 -> Maybe W物 機Get物 (W機 e x w) = Just $ 機mk物 (mappingToList e) (mkSet x) w where mkSet :: X形 -> (M名物 -> Bool) mkSet x = let xs = toList x in \v -> memQ xs v where toList (X名 x) = [名 x] toList (X首尾 m xs) = m : toList xs toList X空 = [] memQ [] _ = False memQ (x:xs) y = x==y || memQ xs y 機mk物 :: List (M名物, W物) -> (M名物 -> Bool) -> W物 -> W物 機mk物 xs q b = mkLet (filter (\(m, _) -> not (q m)) xs) b where mkLet :: List (M名物, W物) -> W物 -> W物 mkLet xs b = 建列 ((mkF (map (\(m, x) -> m) xs) b) : (map (\(m, x) -> x) xs)) where mkF :: List M名物 -> W物 -> W物 mkF xs y = 建式 (建界名["入"]) [建列 (map (\(M名 x) -> 名 x) xs), y] 機Get物 (W界機 (MkJJ界機物 _ _ _ _ x)) = Just x 機Get物 _ = Nothing 算 :: W物 -> Mapping M名物 W物 -> W物 算 _x@(W名 m) e = case mappingRef e (名 m) of Just x -> x Nothing -> 界誤 ["算"] [_x,境To物 e] 算 _x@(W首尾 y x) e | y == 用式名 = let r = do W首尾 f xs <- return x xs' <- 物ToList xs return (f, xs') in case r of Just (f, xs) -> case 算 f e of W引機 f -> 用 f ((境To物 e) : xs) W譯機 f -> 算 (用 f xs) e _ -> 界誤 ["算"] [_x,境To物 e] Nothing -> 界誤 ["算"] [_x,境To物 e] 算 _x@(W首尾 y x) e | y == 用界名 = case x of W首尾 (W名 m) W空 -> case mappingRef e (名 m) of Just x -> x Nothing -> 界誤 ["算"] [_x,境To物 e] _ -> 界誤 ["算"] [_x,境To物 e] 算 _x@(W首尾 f as) e = case 物ToList as of Just xs -> let (xs', f') = (map (\x->算 x e) xs, 算 f e) in case 物To機物 f' of Just f'' -> 用 f'' xs' Nothing -> 界誤 ["用"] [f', 建列 xs'] Nothing -> 界誤 ["算"] [_x,境To物 e] 算 x@(W誤 _) e = 界誤 ["算"] [x,境To物 e] 算 x e = x match :: Mapping M名物 W物 -> X形 -> List W物 -> Maybe (Mapping M名物 W物) match m (X名 x) v = Just (mappingSet m (名 x) (建列 v)) match m X空 [] = Just m match m (X首尾 (M名 x) xs) (v:vs) = match (mappingSet m (名 x) v) xs vs match _ _ _ = Nothing 用 :: J機物 -> List W物 -> W物 用 (J機 e a x) ws = case match e a ws of Just e -> 算 x e Nothing -> 界誤 ["用"] [(機 e a x),建列 ws] 用 (J界機 a_@(MkJJ界機物 _ c f _ _)) ws = if length ws == c then f ws else 界誤 ["用"] [界機 a_,建列 ws]