From 23e8acfc1eaa1702e55f47239e4b4dfbe9d35fca Mon Sep 17 00:00:00 2001
From: sanine <sanine.not@pm.me>
Date: Tue, 21 Nov 2023 11:34:48 -0600
Subject: add connectNeurons

---
 src/Mind.hs | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

(limited to 'src')

diff --git a/src/Mind.hs b/src/Mind.hs
index 45b90da..1ce8ab3 100644
--- a/src/Mind.hs
+++ b/src/Mind.hs
@@ -6,8 +6,11 @@ module Mind
   
   , Network (..)
   , createEmptyNetwork
+  , connectNeurons
   ) where
 
+import Data.Ix
+
 -- index different neuron types
 data NeuronIndex = Input Int | Internal Int | Output Int deriving (Show, Eq)
 
@@ -26,5 +29,45 @@ data Network = Network
   , outputNeurons :: [[Edge]]
   } deriving (Show, Eq)
 
+-- create a completely empty network
 createEmptyNetwork :: Int -> Int -> Int -> Network
 createEmptyNetwork i h o = Network i (replicate h []) (replicate o [])
+
+
+-- connect two neurons together with a new edge
+connectNeurons :: Network -> NeuronIndex -> NeuronIndex -> Float -> Maybe Network
+-- internal sink
+connectNeurons (Network i h o) source (Internal sink) weight = 
+  if (validSource (Network i h o) source) then do
+    newH <- insertEdge h sink $ Edge (source, weight)
+    return $ Network i newH o
+  else Nothing
+-- output sink
+connectNeurons (Network i h o) source (Output sink) weight = 
+  if (validSource (Network i h o) source) then do
+    newO <- insertEdge o sink $ Edge (source, weight)
+    return $ Network i h newO
+  else Nothing
+-- 
+connectNeurons _ _ (Input _) _ = Nothing
+
+
+
+-- helpers for connectNeurons
+
+-- check if a given NeuronIndex can be used as a valid source
+validSource :: Network -> NeuronIndex -> Bool
+validSource _ (Output _) = False
+validSource (Network i _ _) (Input x) = 
+  if (inRange (0, i) x) 
+  then True else False
+validSource (Network _ h _) (Internal x) = 
+  if (inRange (0, length h) x)
+  then True else False
+
+-- insert a new edge into a neuron list, possibly failing
+insertEdge :: [[Edge]] -> Int -> Edge -> Maybe [[Edge]]
+insertEdge ns i e 
+  | (inRange (0, length ns) i) = let (front, es:back) = splitAt i ns
+    in Just $ front ++ [e:es] ++ back
+  | otherwise = Nothing
-- 
cgit v1.2.1