1
Fork 0

Commiting some old changes

This commit is contained in:
Matei Adriel 2023-06-04 15:29:29 +02:00
parent 0bb81bfc46
commit 3f6091369a
7 changed files with 244 additions and 25 deletions

View file

@ -9,3 +9,8 @@
/.psa*
/.spago
dist
*.aux
*.fls
*.fdb_*
*.synctex*
*.log

Binary file not shown.

View 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}

Binary file not shown.

View 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}

View file

@ -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

View 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