Commiting some old changes
This commit is contained in:
parent
0bb81bfc46
commit
3f6091369a
5
purescript/factorio-throughput/.gitignore
vendored
5
purescript/factorio-throughput/.gitignore
vendored
|
@ -9,3 +9,8 @@
|
|||
/.psa*
|
||||
/.spago
|
||||
dist
|
||||
*.aux
|
||||
*.fls
|
||||
*.fdb_*
|
||||
*.synctex*
|
||||
*.log
|
||||
|
|
BIN
purescript/factorio-throughput/idea/example.pdf
Normal file
BIN
purescript/factorio-throughput/idea/example.pdf
Normal file
Binary file not shown.
94
purescript/factorio-throughput/idea/example.tex
Normal file
94
purescript/factorio-throughput/idea/example.tex
Normal file
|
@ -0,0 +1,94 @@
|
|||
\documentclass[a4paper, 12pt]{article}
|
||||
|
||||
\newcommand{\bold}{\textbf}
|
||||
|
||||
\usepackage[english]{babel}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{tikz}
|
||||
\usepackage{indentfirst}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\newcommand{\q2}{\quad\quad}
|
||||
|
||||
\title{\Large{\bold{Moontorio}}}
|
||||
\author{Matei Adriel}
|
||||
\date {}
|
||||
|
||||
\maketitle
|
||||
|
||||
\section{Example 1}
|
||||
|
||||
Solve the following factory:
|
||||
|
||||
\vspace*{20pt}
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\begin{tikzpicture}[shorten >=1pt, auto, node distance={30mm},
|
||||
main/.style = {draw, rectangle}]
|
||||
|
||||
\node[main] (3) {$consumer_1$};
|
||||
\node[main] (1) [above left of=3] {$provider_1$};
|
||||
\node[main] (2) [below left of=3] {$provider_2$};
|
||||
\node[main] (4) [right of=2] {$consumer_2$};
|
||||
|
||||
\draw[->] (1) edge node{$p_1$} (3);
|
||||
\draw[->] (2) edge node{$p_2$} (3);
|
||||
\draw[->] (2) edge node{$p_3$} (4);
|
||||
|
||||
\end{tikzpicture}
|
||||
\caption{Factory}
|
||||
\label{fig:Factory}
|
||||
\end{figure}
|
||||
|
||||
Generating the constraints:
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
|
||||
\begin{equation}
|
||||
p_1(t) < provider_1(t)
|
||||
\end{equation}
|
||||
|
||||
\begin{equation}
|
||||
p_3(t) < consumer_2(t)
|
||||
\end{equation}
|
||||
|
||||
\begin{equation}
|
||||
\begin{split}
|
||||
\begin{cases}
|
||||
\begin{cases}
|
||||
p_2(t) &< \displaystyle\frac{consumer_1(t)}{2}\\
|
||||
p_1(t) &< consumer_1(t) - p_2(t)
|
||||
\end{cases}
|
||||
\ ,&\;\mbox{if } p_1(t) \geq p_2(t)\\\\
|
||||
\begin{cases}
|
||||
p_1(t) &< \displaystyle\frac{consumer_1(t)}{2}\\
|
||||
p_2(t) &< consumer_1(t) - p_1(t)
|
||||
\end{cases}
|
||||
\ ,&\;\mbox{if } p_1(t) < p_2(t)
|
||||
\end{cases}
|
||||
\end{split}
|
||||
\end{equation}
|
||||
|
||||
\begin{equation}
|
||||
\begin{split}
|
||||
\begin{cases}
|
||||
\begin{cases}
|
||||
p_3(t) &< \displaystyle\frac{provider_2(t)}{2}\\
|
||||
p_2(t) &< provider_2(t) - p_3(t)
|
||||
\end{cases}
|
||||
\ ,&\;\mbox{if } p_2(t) \geq p_3(t)\\\\
|
||||
\begin{cases}
|
||||
p_2(t) &< \displaystyle\frac{provider_2(t)}{2}\\
|
||||
p_3(t) &< provider_2(t) - p_3(t)
|
||||
\end{cases}
|
||||
\ ,&\;\mbox{if } p_2(t) < p_3(t)
|
||||
\end{cases}
|
||||
\end{split}
|
||||
\end{equation}
|
||||
|
||||
\caption{Constraints}
|
||||
\label{fig:Constraints}
|
||||
\end{figure}
|
||||
|
||||
\end{document}
|
BIN
purescript/factorio-throughput/idea/hmm.pdf
Normal file
BIN
purescript/factorio-throughput/idea/hmm.pdf
Normal file
Binary file not shown.
77
purescript/factorio-throughput/idea/hmm.tex
Normal file
77
purescript/factorio-throughput/idea/hmm.tex
Normal file
|
@ -0,0 +1,77 @@
|
|||
\documentclass[a4paper, 12pt]{article}
|
||||
|
||||
\newcommand{\bold}{\textbf}
|
||||
|
||||
\usepackage[english]{babel}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{tikz}
|
||||
\usepackage{indentfirst}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\newcommand{\q2}{\quad\quad}
|
||||
|
||||
\title{\Large{\bold{Moontorio}}}
|
||||
\author{Matei Adriel}
|
||||
\date {}
|
||||
|
||||
\maketitle
|
||||
|
||||
\section{Describing a factory}
|
||||
|
||||
A factory is made out of machines. A machine is either a provider, a belt or a consumer. Machines are connected by ports.
|
||||
|
||||
\begin{figure}[h]
|
||||
|
||||
\begin{equation}
|
||||
\begin{split}
|
||||
Machines\ A,\ B,\ C\ &::=\; belt\ p_i\ p_o \\
|
||||
&\quad|\quad provider\ p_1,\ p_2,\ ...\ p_n \\
|
||||
&\quad|\quad consumer\ p_1,\ p_2,\ ...\ p_n
|
||||
\end{split}
|
||||
\end{equation}
|
||||
\caption{Machines}
|
||||
\label{Machines}
|
||||
\end{figure}
|
||||
|
||||
We can represent the factory as a directed graph, with the machines being the nodes and the ports being the edges:
|
||||
|
||||
\vspace*{20pt}
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\begin{tikzpicture}[shorten >=1pt, auto, node distance={50mm},
|
||||
main/.style = {draw, rectangle}]
|
||||
|
||||
\node[main] (1) {$provider_1$};
|
||||
\node[main] (2) [right of=1] {$belt_1$};
|
||||
\node[main] (3) [right of=2] {$consumer_1$};
|
||||
|
||||
\draw[->] (1) edge node{$p_1$} (2);
|
||||
\draw[->] (2) edge node{$p_2$} (3);
|
||||
|
||||
\end{tikzpicture}
|
||||
\caption{Example of a simple factory}
|
||||
\label{SimpleFactory}
|
||||
\end{figure}
|
||||
|
||||
\section{Constraints}
|
||||
The first step of the factory solving process is the constraint generation.
|
||||
We currently use 3 different types of constraints (Figure \ref{Constraints}).
|
||||
Let's take them one step at a time. The first two constrains (
|
||||
$p_k(t) <_{\Leftarrow} f(t)$ and $p_k(t) <_{\Rightarrow} f(t)$
|
||||
) are pretty similar, both limiting the flow through a port.
|
||||
|
||||
\begin{figure}[ht]
|
||||
|
||||
\begin{equation}
|
||||
\begin{split}
|
||||
Constraints\quad C_k\ &::=\; p_k(t) <_{\Leftarrow} f(t) \\
|
||||
&\quad|\quad p_k(t) <_{\Rightarrow} f(t) \\
|
||||
&\quad|\quad p_1(t) = p_2(f(t))
|
||||
\end{split}
|
||||
\end{equation}
|
||||
\caption{Constraints}
|
||||
\label{Constraints}
|
||||
\end{figure}
|
||||
|
||||
\end{document}
|
|
@ -6,7 +6,7 @@ import Data.Array (length, mapWithIndex)
|
|||
import Data.Array as Array
|
||||
import Data.Either (Either)
|
||||
import Data.Foldable (foldMap, for_, minimum)
|
||||
import Data.FoldableWithIndex (forWithIndex_)
|
||||
import Data.FoldableWithIndex (foldlWithIndex, forWithIndex_)
|
||||
import Data.Generic.Rep (class Generic)
|
||||
import Data.HashMap (HashMap)
|
||||
import Data.HashMap as HashMap
|
||||
|
@ -16,12 +16,11 @@ import Data.Int (toNumber)
|
|||
import Data.Lens (Lens')
|
||||
import Data.Lens.Record (prop)
|
||||
import Data.List (List(..), (:))
|
||||
import Data.List as List
|
||||
import Data.Maybe (Maybe(..), fromJust, fromMaybe)
|
||||
import Data.Number (infinity)
|
||||
import Data.Show.Generic (genericShow)
|
||||
import Data.Traversable (for)
|
||||
import Data.Tuple (Tuple(..), fst, uncurry)
|
||||
import Data.Tuple (Tuple(..), fst, snd, uncurry)
|
||||
import Data.Tuple.Nested (type (/\), (/\))
|
||||
import Functorio.Lens (modifyAt)
|
||||
import Math (sin)
|
||||
|
@ -70,8 +69,8 @@ blueBelt :: BeltConfig
|
|||
blueBelt = { speed: 45.0, delay: 4.0/8.0 }
|
||||
|
||||
-- | Example factory
|
||||
myFactory :: Factory
|
||||
myFactory = Map.fromArray machines
|
||||
myFactory1 :: Factory
|
||||
myFactory1 = Map.fromArray machines
|
||||
where
|
||||
machines = mapWithIndex Tuple
|
||||
[ Provider [0, 1] $ startsAtZero $ \t -> 40.0 + 10.0 * sin t
|
||||
|
@ -82,6 +81,19 @@ myFactory = Map.fromArray machines
|
|||
, Consumer 4
|
||||
]
|
||||
|
||||
myFactory :: Factory
|
||||
myFactory = Map.fromArray machines
|
||||
where
|
||||
machines = mapWithIndex Tuple
|
||||
[ Provider [0, 1, 2] $ startsAtZero $ \t -> 80.0
|
||||
, Belt { input: 0, output: 3, config: yellowBelt }
|
||||
, Belt { input: 1, output: 4, config: redBelt }
|
||||
, Belt { input: 2, output: 5, config: blueBelt }
|
||||
, Consumer 3
|
||||
, Consumer 4
|
||||
, Consumer 5
|
||||
]
|
||||
|
||||
---------- Helpers for real functions
|
||||
type Endomorphism a = a -> a
|
||||
|
||||
|
@ -190,7 +202,7 @@ tryFindBoundImpl (targetId /\ targetSide) = do
|
|||
evalExpr expr <*> pure time
|
||||
BiRelationship id raw
|
||||
| Just relationship <- focusBiRelationship (targetId /\ targetSide) raw -> do
|
||||
f <- once id fail $ tryFindBoundImpl relationship.p2
|
||||
f <- once id fail $ tryFindValueImpl $ fst relationship.p2
|
||||
f (relationship.p1top2 time)
|
||||
_ -> fail
|
||||
# runReader constraints
|
||||
|
@ -225,29 +237,27 @@ collectConstraintsImpl at = case _ of
|
|||
Provider for amount -> do
|
||||
forWithIndex_ for \index id -> do
|
||||
let limit ports time
|
||||
= outputs ports time
|
||||
# Array.findMap (\(id' /\ f) -> if id == id' then Just (f time) else Nothing)
|
||||
# unsafePartial fromJust -- TODO: error handling
|
||||
= ports
|
||||
# map (\port -> port.id /\ port.maxOutput time)
|
||||
# outputs (amount time)
|
||||
# Array.findMap (\(id' /\ f) -> if id == id' then Just f else Nothing)
|
||||
# unsafePartial fromJust
|
||||
constrain $ Limit (PortDependent for limit) Input id
|
||||
where
|
||||
outputs :: Array PortData -> Number -> Array (PortId /\ RealFunction)
|
||||
outputs ports time
|
||||
= outputsImpl (length ports) (List.fromFoldable sorted) amount
|
||||
outputs :: Number -> Array (PortId /\ Number) -> Array (PortId /\ Number)
|
||||
outputs total ports
|
||||
= ports
|
||||
# Array.sortWith snd
|
||||
# foldlWithIndex (\index (past /\ remaining) (id /\ value) -> do
|
||||
let current
|
||||
| lengthLeft <- remaining / toNumber (count - index), value >= lengthLeft = lengthLeft
|
||||
| otherwise = value
|
||||
((id /\ current):past) /\ (remaining - current))
|
||||
(Nil /\ total)
|
||||
# fst
|
||||
# Array.fromFoldable
|
||||
# Array.zipWith (_.id >>> Tuple) sorted
|
||||
where
|
||||
sorted :: Array PortData
|
||||
sorted = Array.sortWith (_.maxOutput >>> (#) time) ports
|
||||
|
||||
outputsImpl :: Int -> List PortData -> RealFunction -> List RealFunction
|
||||
outputsImpl 1 (head:Nil) remaining = pure \time -> min (head.maxOutput time) (remaining time)
|
||||
outputsImpl n (head:tail) remaining = current:(outputsImpl (n - 1) tail $ remaining - current)
|
||||
where
|
||||
current time
|
||||
| head.maxOutput time >= (remaining time) / (toNumber n) = (remaining time) / (toNumber n)
|
||||
| otherwise = head.maxOutput time
|
||||
outputsImpl _ _ _ = Nil
|
||||
|
||||
count = length ports
|
||||
Consumer for -> do
|
||||
constrain $ Limit (Literal infinity) Output for
|
||||
Belt { input, output, config } -> do
|
||||
|
|
33
purescript/factorio-throughput/src/Utils/Ord.purs
Normal file
33
purescript/factorio-throughput/src/Utils/Ord.purs
Normal file
|
@ -0,0 +1,33 @@
|
|||
module Moontorio.Ord.Extra (Side, left, right, OrderedArray, binarySearch) where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Array (length, unsafeIndex)
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Partial.Unsafe (unsafePartial)
|
||||
|
||||
type OrderedArray = Array
|
||||
newtype Side = Side Boolean
|
||||
|
||||
left :: Side
|
||||
left = Side false
|
||||
|
||||
right :: Side
|
||||
right = Side true
|
||||
|
||||
binarySearch :: forall a. (Int -> a -> Side) -> OrderedArray a -> Maybe Int
|
||||
binarySearch f arr = unsafePartial $ findImpl 0 (length arr)
|
||||
where
|
||||
findImpl :: Partial => _
|
||||
findImpl start length | length == 0 = Nothing
|
||||
| length == 1 = Just start
|
||||
| otherwise = do
|
||||
let middle = start + length / 2
|
||||
let element = unsafeIndex arr middle
|
||||
if f middle element == left then
|
||||
findImpl start (middle - start)
|
||||
else
|
||||
findImpl middle (length + start - middle)
|
||||
|
||||
---------- Typeclass instances
|
||||
derive instance eqSide :: Eq Side
|
Loading…
Reference in a new issue