546 lines
36 KiB
HTML
546 lines
36 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/flow.clj </title>
|
|
</head>
|
|
<body>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
001 (ns mw-engine.flow
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
002 "Allow flows of values between cells in the world.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
003
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
004 The design here is: a flow object is a map with the following properties:
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
005
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
006 1. `:source`, whose value is a location;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
007 2. `:destination`, whose value is a location;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
008 3. `:property`, whose value is a keyword;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
009 4. `:quantity`, whose value is a positive real number.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
010
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
011 A location object is a map with the following properties:
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
012
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
013 1. `:x`, whose value is a natural number not greater than the extent of the world;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
014 2. `:y`, whose value is a natural number not greater than the extent of the world.
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
015
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
016 To execute a flow is transfer the quantity specified of the property specified
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
017 from the cell at the source specified to the cell at the destination specified;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
018 if the source doesn't have sufficient of the property, then all it has should
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
019 be transferred, but no more: properties to be flowed cannot be pulled negative.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
020
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
021 Flowing values through the world is consequently a two stage process: firstly
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
022 there's a planning stage, in which all the flows to be executed are computed
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
023 without changing the world, and then an execution stage, where they're all
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
024 executed. This namespace deals with mainly with execution."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
025 (:require [mw-engine.utils :refer [add-history-event get-cell get-num
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
026 in-bounds? map-world merge-cell rule-type]]
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
027 [taoensso.timbre :refer [info warn]]))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
028
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
029 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
030 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
031 ;;;; mw-engine: the state/transition engine of MicroWorld.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
032 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
033 ;;;; This program is free software; you can redistribute it and/or
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
034 ;;;; modify it under the terms of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
035 ;;;; as published by the Free Software Foundation; either version 2
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
036 ;;;; of the License, or (at your option) any later version.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
037 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
038 ;;;; This program is distributed in the hope that it will be useful,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
039 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
040 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
041 ;;;; GNU General Public License for more details.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
042 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
043 ;;;; You should have received a copy of the GNU General Public License
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
044 ;;;; along with this program; if not, write to the Free Software
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
045 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
046 ;;;; USA.
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
047 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
048 ;;;; Copyright (C) 2014 Simon Brooke
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
049 ;;;;
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
050 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
051
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
052 (defn coordinate?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
053 "Return `true` if this object `o` is a valid coordinate with respect to
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
054 this `world`, else `false`. Assumes square worlds."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
055 [o world]
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
056 (try
|
|
</span><br/>
|
|
<span class="covered" title="14 out of 14 forms covered">
|
|
057 (and (or (zero? o) (pos-int? o))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
058 (< o (count world)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
059 (catch Exception e
|
|
</span><br/>
|
|
<span class="covered" title="20 out of 20 forms covered">
|
|
060 (warn (format "Not a valid coordinate: %s; %s" o (.getMessage e)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
061 false)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
062
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
063 (defn location?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
064 "Return `true` if this object `o` is a location as defined above with respect to
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
065 this `world`, else `false`."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
066 [o world]
|
|
</span><br/>
|
|
<span class="partial" title="1 out of 2 forms covered">
|
|
067 (try
|
|
</span><br/>
|
|
<span class="partial" title="14 out of 16 forms covered">
|
|
068 (and (map? o)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
069 (integer? (:x o))
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
070 (integer? (:y o))
|
|
</span><br/>
|
|
<span class="covered" title="8 out of 8 forms covered">
|
|
071 (in-bounds? world (:x o) (:y o)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
072 (catch Exception e
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 20 forms covered">
|
|
073 (warn (format "Not a valid location: %s; %s" o (.getMessage e)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
074 false)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
075
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
076 (defn flow?
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
077 "Return `true` if this object `o` is a flow as defined above with respect to
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
078 this `world`, else `false`. Assumes square worlds."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
079 [o world]
|
|
</span><br/>
|
|
<span class="partial" title="1 out of 2 forms covered">
|
|
080 (try
|
|
</span><br/>
|
|
<span class="partial" title="16 out of 20 forms covered">
|
|
081 (and (map? o)
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
082 (location? (:source o) world)
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
083 (location? (:destination o) world)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
084 (keyword? (:property o))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
085 (pos? (:quantity o)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
086 (catch Exception e
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 20 forms covered">
|
|
087 (warn (format "Not a valid flow: %s; %s" o (.getMessage e)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
088 false)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
089
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
090 (defn execute
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
091 "Return a world like this `world`, except with the quantity of the property
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
092 described in this `flow` object transferred from the source of that flow
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
093 to its destination."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
094 [world flow]
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
095 (try
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
096 (let [sx (-> flow :source :x)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
097 sy (-> flow :source :y)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
098 source (get-cell world sx sy)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
099 dx (-> flow :destination :x)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
100 dy (-> flow :destination :y)
|
|
</span><br/>
|
|
<span class="covered" title="5 out of 5 forms covered">
|
|
101 dest (get-cell world dx dy)
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
102 p (:property flow)
|
|
</span><br/>
|
|
<span class="partial" title="16 out of 22 forms covered">
|
|
103 q (min (:quantity flow) (get-num source p))
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
104 s' (add-history-event
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
105 (assoc source p (- (source p) q))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
106 (:rule flow)
|
|
</span><br/>
|
|
<span class="covered" title="13 out of 13 forms covered">
|
|
107 {:direction :sent :other {:x dx :y dy} :property p :quantity q})
|
|
</span><br/>
|
|
<span class="covered" title="2 out of 2 forms covered">
|
|
108 d' (add-history-event
|
|
</span><br/>
|
|
<span class="partial" title="20 out of 24 forms covered">
|
|
109 (assoc dest p (+ (get-num dest p) q))
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
110 (:rule flow)
|
|
</span><br/>
|
|
<span class="covered" title="13 out of 13 forms covered">
|
|
111 {:direction :received :other {:x sx :y sy} :property p :quantity q})]
|
|
</span><br/>
|
|
<span class="covered" title="6 out of 6 forms covered">
|
|
112 (if (= q (:quantity flow))
|
|
</span><br/>
|
|
<span class="covered" title="18 out of 18 forms covered">
|
|
113 (info (format "Moving %f units of %s from %d,%d to %d,%d"
|
|
</span><br/>
|
|
<span class="covered" title="9 out of 9 forms covered">
|
|
114 (float q) (name p) sx sy dx dy))
|
|
</span><br/>
|
|
<span class="covered" title="18 out of 18 forms covered">
|
|
115 (warn (format "Moving %s from %d,%d to %d,%d; %f units ordered but only %f available"
|
|
</span><br/>
|
|
<span class="covered" title="13 out of 13 forms covered">
|
|
116 (name p) sx sy dx dy (float (:quantity flow)) (float q))))
|
|
</span><br/>
|
|
<span class="covered" title="7 out of 7 forms covered">
|
|
117 (merge-cell (merge-cell world s') d'))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
118 (catch Exception e
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 20 forms covered">
|
|
119 (warn (format "Failed to execute flow %s: %s" flow (.getMessage e)))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
120 ;; return the world unmodified.
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
121 world)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
122
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
123 (defn execute-flows
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
124 "Return a world like this `world`, but with each of these flows executed."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
125 [world flows]
|
|
</span><br/>
|
|
<span class="covered" title="12 out of 12 forms covered">
|
|
126 (reduce execute world (filter #(flow? % world) flows)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
127
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
128 (defn- plan-cell-flows
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
129 [world cell rules]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
130 (map ;; across all the rules
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
131 (fn [rule] (let [r (try
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 7 forms covered">
|
|
132 (apply rule (list cell world))
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
133 (catch Exception any
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 4 forms covered">
|
|
134 (throw (ex-info "Planning of flows failed"
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 8 forms covered">
|
|
135 (merge (meta rule) {:cell cell})
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
136 any))))]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 12 forms covered">
|
|
137 (when r (map #(assoc % :rule rule) r))))
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
138 rules))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
139
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
140 (defn plan-flows
|
|
</span><br/>
|
|
<span class="partial" title="3 out of 4 forms covered">
|
|
141 "Plan, but do not execute, all the flows in this `world` implied by those of
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
142 these `rules` (which are expected to be pre-compiled) which are
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
143 flow rules. Return the list of plans, as flow objects."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
144 [world rules]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 3 forms covered">
|
|
145 (remove nil?
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
146 (flatten
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 2 forms covered">
|
|
147 (map-world
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
148 world
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 1 forms covered">
|
|
149 plan-cell-flows
|
|
</span><br/>
|
|
<span class="partial" title="4 out of 17 forms covered">
|
|
150 (list (filter #(= :flow (rule-type %)) rules))))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
151
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
152 (defn flow-world
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
153 "Return a world derived from this `world` by applying the flow rules
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
154 found among these `rules` to each cell, and executing all the flows
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
155 planned."
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
156 [world rules]
|
|
</span><br/>
|
|
<span class="not-covered" title="0 out of 7 forms covered">
|
|
157 (execute-flows world (plan-flows world rules)))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
158
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
159 ;; building blocks for compiled flow rules
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
160
|
|
</span><br/>
|
|
<span class="covered" title="32 out of 32 forms covered">
|
|
161 (defmacro create-location
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
162 [cell]
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
163 `(select-keys ~cell [:x :y]))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
164
|
|
</span><br/>
|
|
<span class="covered" title="56 out of 56 forms covered">
|
|
165 (defmacro create-flow-quantity
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
166 [source dest prop quantity]
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
167 `{:source (create-location ~source)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
168 :destination (create-location ~dest)
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
169 :prop ~prop
|
|
</span><br/>
|
|
<span class="covered" title="1 out of 1 forms covered">
|
|
170 :quantity ~quantity})
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
171
|
|
</span><br/>
|
|
<span class="covered" title="48 out of 48 forms covered">
|
|
172 (defmacro create-flow-fraction
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
173 [source dest prop fraction]
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
174 `(create-flow-quantity ~source ~dest ~prop
|
|
</span><br/>
|
|
<span class="covered" title="3 out of 3 forms covered">
|
|
175 (* ~fraction (get-num ~source ~prop))))
|
|
</span><br/>
|
|
<span class="blank" title="0 out of 0 forms covered">
|
|
176
|
|
</span><br/>
|
|
<span class="covered" title="36 out of 36 forms covered">
|
|
177 (defmacro create-flow-percent
|
|
</span><br/>
|
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
178 [source dest prop percent]
|
|
</span><br/>
|
|
<span class="covered" title="4 out of 4 forms covered">
|
|
179 `(create-flow-fraction ~source ~dest ~prop (/ ~percent 100)))
|
|
</span><br/>
|
|
</body>
|
|
</html>
|