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* /.psa*
/.spago /.spago
dist 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.Array as Array
import Data.Either (Either) import Data.Either (Either)
import Data.Foldable (foldMap, for_, minimum) import Data.Foldable (foldMap, for_, minimum)
import Data.FoldableWithIndex (forWithIndex_) import Data.FoldableWithIndex (foldlWithIndex, forWithIndex_)
import Data.Generic.Rep (class Generic) import Data.Generic.Rep (class Generic)
import Data.HashMap (HashMap) import Data.HashMap (HashMap)
import Data.HashMap as HashMap import Data.HashMap as HashMap
@ -16,12 +16,11 @@ import Data.Int (toNumber)
import Data.Lens (Lens') import Data.Lens (Lens')
import Data.Lens.Record (prop) import Data.Lens.Record (prop)
import Data.List (List(..), (:)) import Data.List (List(..), (:))
import Data.List as List
import Data.Maybe (Maybe(..), fromJust, fromMaybe) import Data.Maybe (Maybe(..), fromJust, fromMaybe)
import Data.Number (infinity) import Data.Number (infinity)
import Data.Show.Generic (genericShow) import Data.Show.Generic (genericShow)
import Data.Traversable (for) import Data.Traversable (for)
import Data.Tuple (Tuple(..), fst, uncurry) import Data.Tuple (Tuple(..), fst, snd, uncurry)
import Data.Tuple.Nested (type (/\), (/\)) import Data.Tuple.Nested (type (/\), (/\))
import Functorio.Lens (modifyAt) import Functorio.Lens (modifyAt)
import Math (sin) import Math (sin)
@ -70,8 +69,8 @@ blueBelt :: BeltConfig
blueBelt = { speed: 45.0, delay: 4.0/8.0 } blueBelt = { speed: 45.0, delay: 4.0/8.0 }
-- | Example factory -- | Example factory
myFactory :: Factory myFactory1 :: Factory
myFactory = Map.fromArray machines myFactory1 = Map.fromArray machines
where where
machines = mapWithIndex Tuple machines = mapWithIndex Tuple
[ Provider [0, 1] $ startsAtZero $ \t -> 40.0 + 10.0 * sin t [ Provider [0, 1] $ startsAtZero $ \t -> 40.0 + 10.0 * sin t
@ -82,6 +81,19 @@ myFactory = Map.fromArray machines
, Consumer 4 , 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 ---------- Helpers for real functions
type Endomorphism a = a -> a type Endomorphism a = a -> a
@ -190,7 +202,7 @@ tryFindBoundImpl (targetId /\ targetSide) = do
evalExpr expr <*> pure time evalExpr expr <*> pure time
BiRelationship id raw BiRelationship id raw
| Just relationship <- focusBiRelationship (targetId /\ targetSide) raw -> do | 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) f (relationship.p1top2 time)
_ -> fail _ -> fail
# runReader constraints # runReader constraints
@ -225,29 +237,27 @@ collectConstraintsImpl at = case _ of
Provider for amount -> do Provider for amount -> do
forWithIndex_ for \index id -> do forWithIndex_ for \index id -> do
let limit ports time let limit ports time
= outputs ports time = ports
# Array.findMap (\(id' /\ f) -> if id == id' then Just (f time) else Nothing) # map (\port -> port.id /\ port.maxOutput time)
# unsafePartial fromJust -- TODO: error handling # outputs (amount time)
# Array.findMap (\(id' /\ f) -> if id == id' then Just f else Nothing)
# unsafePartial fromJust
constrain $ Limit (PortDependent for limit) Input id constrain $ Limit (PortDependent for limit) Input id
where where
outputs :: Array PortData -> Number -> Array (PortId /\ RealFunction) outputs :: Number -> Array (PortId /\ Number) -> Array (PortId /\ Number)
outputs ports time outputs total ports
= outputsImpl (length ports) (List.fromFoldable sorted) amount = 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.fromFoldable
# Array.zipWith (_.id >>> Tuple) sorted
where where
sorted :: Array PortData count = length ports
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
Consumer for -> do Consumer for -> do
constrain $ Limit (Literal infinity) Output for constrain $ Limit (Literal infinity) Output for
Belt { input, output, config } -> do 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