### Solve a simple problem with qdsl Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md This example demonstrates how to define and solve a basic constraint satisfaction problem using the `qdsl` macro and `solve` function. It defines two integer variables 'r' and 'p' and two linear equality constraints. ```clojure (require '[quandary.api :refer [solve qdsl]]) (solve (qdsl {} {"r" [:range 0 100] "p" [:range 0 100]} [= (+ "r" "p") 20] [= (+ (* 4 "r") (* 2 "p")) 56]) {:enumerate-all true}) ;; => [{"r" 8, "p" 12}] ``` -------------------------------- ### Define fixed-size interval domain Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Defines a scheduling interval for 'task' with a fixed size of 5, anchored at the start time specified by the 'task.start' variable. ```clojure "task" [:fixed-size-interval "task.start" 5] ``` -------------------------------- ### Build and Test Commands Source: https://github.com/mlimotte/quandary/blob/main/README.md CLI commands for building the project and running tests. ```bash clj -T:build jar ``` ```bash clj -T:build clean ``` ```bash clj -M:test ``` ```bash clj -M:test -v quandary.quandary-test/test-name ``` -------------------------------- ### qdsl-from-resource Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Loads a problem definition from an EDN file on the classpath with variable injection. ```APIDOC ## qdsl-from-resource ### Description Loads a problem definition from an EDN file on the classpath, allowing for parameterized variable name injection. ### Parameters - **options** (map) - Contains :tag key. - **path** (string) - Path to the EDN file. - **args** (vector) - Vector of values to inject into the problem definition. ### Example (qdsl-from-resource {:tag "my-problem"} "problems/layout.edn" [room-width room-height]) ``` -------------------------------- ### Define and Solve Rabbits and Pheasants Problem with qdsl Source: https://context7.com/mlimotte/quandary/llms.txt Use the `qdsl` macro to define domains and equations for a constraint problem, then pass the result to `solve`. The `{:enumerate-all true}` option finds all satisfying assignments. ```clojure (require '[quandary.api :refer [solve qdsl collate $ $#]]) ;; Classic "Rabbits and Pheasants" problem: ;; In a field of rabbits and pheasants, there are 20 heads and 56 legs. ;; How many rabbits and pheasants are there? ;; (Rabbits have 4 legs, pheasants have 2) (solve (qdsl {} ({"r" [:range 0 100] ; rabbits: integer in [0, 100] "p" [:range 0 100]} ; pheasants: integer in [0, 100] [= (+ "r" "p") 20] ; total heads = 20 [= (+ (* 4 "r") (* 2 "p")) 56]) ; total legs = 56 {:enumerate-all true}) ;; => [{"r" 8, "p" 12}] ``` -------------------------------- ### Load problem from resource Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Loads a problem definition from an EDN file on the classpath with parameterized variable injection. ```clojure (qdsl-from-resource {:tag "my-problem"} "problems/layout.edn" [room-width room-height]) ``` ```edn {:in [room-width room-height]} {"width" [:range 0 room-width] "height" [:range 0 room-height]} [<= (+ "width" "height") 100] ``` -------------------------------- ### Solve Constraint Satisfaction Problem with qdsl Source: https://github.com/mlimotte/quandary/blob/main/README.md Defines variables and constraints using the qdsl macro and solves for satisfying assignments. ```clojure (require '[quandary.api :as api]) ;; Rabbits and pheasants: 20 heads, 56 legs. How many of each? (let [rules (api/qdsl {} {"r" [:range 0 100] "p" [:range 0 100]} [= (+ "r" "p") 20] [= (+ (* 4 "r") (* 2 "p")) 56])] (api/solve rules {:enumerate-all true})) ;; => [{"r" 8, "p" 12}] ``` -------------------------------- ### Configure Solver Options Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Pass a map of options to the solve function to control performance, limits, and output behavior. ```clojure (solve problem {:timeout 20.0 ; seconds to run before stopping (default: 20) :enumerate-all true ; find all solutions (incompatible with :num-workers > 1) :num-workers 4 ; parallel workers (default: 0 = all cores) :relative-gap-limit 0.05 ; stop when within 5% of optimal :objective [:minimize "cost"] ; or [:maximize "cost"] :limit 10 ; cap the number of returned solutions :check-inbalance? false ; disable mismatch check (default: true) :retain-temp? true}) ; include TEMP variables in results (default: false) ``` -------------------------------- ### Parse Infix Equations for Quick Exploration Source: https://context7.com/mlimotte/quandary/llms.txt Uses parse-equations for prototyping simple problems with infix string syntax. ```clojure (require '[quandary.quandary :as q]) ;; String-based equation syntax for simple problems (q/solve-equations {"r" [:range 0 100] "p" [:range 0 100]} (q/parse-equations "r + p = 20" "4 r + 2 p = 56")) ;; => [{"r" 8, "p" 12}] ;; Non-linear constraints work too (q/solve-equations {"x" [:range 0 20] "y" [:range 0 20] "z" [36]} (q/parse-equations "2 x y = z")) ; 2 * x * y = 36 ;; => [{"x" 1, "y" 18, "z" 36} {"x" 2, "y" 9, "z" 36} ...] ``` -------------------------------- ### Inspect qdsl compilation Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Shows the underlying map structure that qdsl compiles to. ```clojure {:domain {"a" [:range 0 5], "b" [:range 0 5]} :equations [...]} ``` ```clojure (:equations (qdsl {} {"a" [:range 0 5] "b" [:range 0 5]} [= (+ "a" (* 2 "b")) 10])) ;; => ((= [["a"] [2 "b"]] [[10]])) ``` -------------------------------- ### qdsl Source: https://context7.com/mlimotte/quandary/llms.txt Defines a constraint problem with domains and equations. ```APIDOC ## qdsl ### Description Constructs a problem definition map using variable domains and a set of constraints. ### Parameters - **metadata** (map) - Required - Metadata for the problem. - **domains** (map) - Required - A map of variable names to their domain types (e.g., [:range 0 100], [:boolean]). - **equations** (vector) - Required - A series of s-expressions defining constraints. ### Request Example (qdsl {} {"a" [:boolean]} [= "a" 1]) ``` -------------------------------- ### Arithmetic Comparisons and Range Forms in Quandary Source: https://context7.com/mlimotte/quandary/llms.txt Demonstrates defining variables with ranges and applying arithmetic comparisons and range constraints. Ensure all necessary functions are required from quandary.api. ```clojure (require '[quandary.api :refer [solve qdsl]]) ;; Arithmetic comparisons with range forms (solve (qdsl {} {"x" [:range 0 100] "y" [:range 0 100] "z" [:range 0 100]} [= (+ "x" (* 2 "y")) 10] ; x + 2y = 10 [<= 0 "z" 50] ; 0 <= z <= 50 (three-arg range form) [!= "x" "y"]) ; x != y {:enumerate-all true}) ``` -------------------------------- ### Parse string equations Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Uses infix string syntax to define equations for the solver. Limited to basic arithmetic and comparison operators. ```clojure (require '[quandary.quandary :as q]) (q/solve-equations {"r" [:range 0 100] "p" [:range 0 100]} (q/parse-equations "r + p = 20" "4 r + 2 p = 56")) ;; => [{"r" 8, "p" 12}] ``` -------------------------------- ### Find All Solutions with solve Function Source: https://context7.com/mlimotte/quandary/llms.txt The `solve` function executes a constraint problem definition. Use `{:enumerate-all true}` to find all possible solutions. Options like `:timeout` and `:num-workers` can be specified. ```clojure (require '[quandary.api :refer [solve qdsl]]) ;; Find all solutions where x + y = 10 and both are in range [0, 10] (solve (qdsl {} ({"x" [:range 0 10] "y" [:range 0 10]} [= (+ "x" "y") 10])) {:enumerate-all true ; find all solutions :timeout 20.0 ; max seconds to run (default: 20) :num-workers 0}) ; parallel workers (0 = all cores) ;; => [{"x" 0, "y" 10} {"x" 1, "y" 9} {"x" 2, "y" 8} ...] ``` -------------------------------- ### qdsl Macro - Define Constraint Problems Source: https://context7.com/mlimotte/quandary/llms.txt The `qdsl` macro is the primary way to define constraint satisfaction problems. It compiles domain maps and equation vectors into a format suitable for the `solve` function. ```APIDOC ## qdsl Macro - Define Constraint Problems ### Description The `qdsl` macro is the recommended way to express constraint satisfaction problems. It compiles domain maps and equation vectors into a format suitable for the `solve` function. The body consists of any number of domain maps and equation vectors interleaved in any order—these are all solved simultaneously. ### Method Macro ### Endpoint N/A (Macro) ### Parameters #### Request Body - **domains** (map) - Required - A map defining the possible values for each variable. - **equations** (vector) - Required - A vector of constraints that the variables must satisfy. ### Request Example ```clojure (require '[quandary.api :refer [solve qdsl $ $#]]) ;; Classic "Rabbits and Pheasants" problem: ;; In a field of rabbits and pheasants, there are 20 heads and 56 legs. ;; How many rabbits and pheasants are there? ;; (Rabbits have 4 legs, pheasants have 2) (solve (qdsl {} {"r" [:range 0 100] ; rabbits: integer in [0, 100] "p" [:range 0 100]} ; pheasants: integer in [0, 100] [= (+ "r" "p") 20] ; total heads = 20 [= (+ (* 4 "r") (* 2 "p")) 56]) ; total legs = 56 {:enumerate-all true}) ;; => [{"r" 8, "p" 12}] ``` ### Response #### Success Response (200) - **solutions** (sequence of maps) - A sequence of maps, where each map represents a valid assignment of variables that satisfies all constraints. ``` -------------------------------- ### Composing Problems with `collate` and Reusable Constraints Source: https://context7.com/mlimotte/quandary/llms.txt Shows how to combine multiple constraint sets using `collate` and define reusable constraint functions with namespaced variables using `$`. Ensure `collate` and `$` are required from `quandary.api`. ```clojure (require '[quandary.api :refer [solve qdsl collate $]]) ;; Reusable constraint function using $ for namespaced variables (defn room-constraints [room-name max-perimeter] (qdsl {} {($ room-name "width") [:range 1 500] ($ room-name "height") [:range 1 500]} [<= (+ ($ room-name "width") ($ room-name "height")) max-perimeter])) ;; Combine constraints for multiple rooms (solve (collate (room-constraints "kitchen" 100) (room-constraints "bedroom" 80) (qdsl {} ;; Kitchen must be bigger than bedroom [>= ($ "kitchen" "width") ($ "bedroom" "width")])) {:limit 1}) ;; Variables: "kitchen.width", "kitchen.height", "bedroom.width", "bedroom.height" ``` -------------------------------- ### Conditional Constraints with `:only-enforce-if` and `:only-enforce-else` Source: https://context7.com/mlimotte/quandary/llms.txt Explains how to apply constraints conditionally based on a boolean variable using `:only-enforce-if`. The optional `:only-enforce-else` clause specifies constraints to apply when the condition is false. ```clojure (require '[quandary.api :refer [solve qdsl]]) ;; Different constraints based on mode selection (solve (qdsl {} {"mode" [:boolean] "x" [:range 0 100] "y" [:range 0 100]} [:only-enforce-if "mode" [= "x" 10] [= "y" 20] :only-enforce-else [= "x" 50] [= "y" 50]]) {:enumerate-all true}) ;; => [{"mode" 0, "x" 50, "y" 50} {"mode" 1, "x" 10, "y" 20}] ``` -------------------------------- ### solve Function - Execute the Solver Source: https://context7.com/mlimotte/quandary/llms.txt The `solve` function takes a problem definition and an options map, then runs the CP-SAT solver. It returns a sequence of solution maps. ```APIDOC ## solve Function - Execute the Solver ### Description The `solve` function takes a problem definition (from `qdsl` or `collate`) and an options map, then runs the CP-SAT solver. It returns a sequence of solution maps where keys are variable names and values are the solved integers. ### Method Function ### Endpoint N/A (Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **problem_definition** (any) - Required - The constraint problem definition, typically generated by `qdsl` or `collate`. - **options** (map) - Optional - A map of solver options. - **enumerate-all** (boolean) - If true, find all possible solutions. - **timeout** (number) - Maximum seconds to run the solver (default: 20.0). - **num-workers** (integer) - Number of parallel workers (0 means all cores). - **objective** (vector) - Defines an optimization objective, e.g., `[:minimize "cost"]` or `[:maximize "profit"]`. - **limit** (integer) - The number of solutions to return (useful with optimization). ### Request Example ```clojure (require '[quandary.api :refer [solve qdsl]]) ;; Find all solutions where x + y = 10 and both are in range [0, 10] (solve (qdsl {} {"x" [:range 0 10] "y" [:range 0 10]} [= (+ "x" "y") 10]) {:enumerate-all true ; find all solutions :timeout 20.0 ; max seconds to run (default: 20) :num-workers 0}) ; parallel workers (0 = all cores) ;; => [{"x" 0, "y" 10} {"x" 1, "y" 9} {"x" 2, "y" 8} ...] ;; Optimization: minimize cost (solve (qdsl {} {"items" [:range 1 10] "cost" [:range 0 1000]} [= "cost" (* 15 "items")] [>= "items" 3]) {:objective [:minimize "cost"] :limit 1}) ;; => [{"items" 3, "cost" 45}] ``` ### Response #### Success Response (200) - **solutions** (sequence of maps) - A sequence of maps, where each map represents a solution found by the solver. ``` -------------------------------- ### parse-equations Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Parses infix string syntax into equation format. ```APIDOC ## quandary.quandary/parse-equations ### Description Accepts a simple infix string syntax for quick exploration of equations. Supports +, -, *, and comparison operators (=, <, >, <=, >=, !=). ### Example (q/solve-equations {"r" [:range 0 100] "p" [:range 0 100]} (q/parse-equations "r + p = 20" "4 r + 2 p = 56")) ``` -------------------------------- ### Max Equality Constraint in Quandary Source: https://context7.com/mlimotte/quandary/llms.txt Demonstrates using `add-max-equality` to set a variable equal to the maximum of other variables. Ensure variables have appropriate range definitions. ```clojure ;; Max/min equality (solve (qdsl {} {"a" [:range 0 10] "b" [20] "answer" [:range 0 100]} [add-max-equality "answer" "a" "b"]) ; answer = max(a, b) {:limit 1}) ;; => [{"a" 0, "b" 20, "answer" 20}] ``` -------------------------------- ### Minimize Objective with solve Function Source: https://context7.com/mlimotte/quandary/llms.txt The `solve` function can perform optimization. Specify an objective using `{:objective [:minimize "variable"]}` or `{:objective [:maximize "variable"]}`. `:limit 1` is often used with optimization to find a single best solution. ```clojure (solve (qdsl {} ({"items" [:range 1 10] "cost" [:range 0 1000]} [= "cost" (* 15 "items")]) [>= "items" 3]) {:objective [:minimize "cost"] :limit 1}) ;; => [{"items" 3, "cost" 45}] ``` -------------------------------- ### Basic Equation Vectors Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Use equation vectors for defining constraints. Operators are symbols, and arguments can be variables, arithmetic s-expressions, or literals. Supports three-argument range forms for comparison operators. ```clojure [= (+ "x" "y") 10] ``` ```clojure [<= "x" "y"] ``` ```clojure [<= 0 "x" 10] ``` -------------------------------- ### Boolean Aggregate Constraints in Quandary Source: https://context7.com/mlimotte/quandary/llms.txt Illustrates using boolean aggregate functions like `add-bool-or` to enforce conditions such as 'at least one variable is true'. Requires boolean variables to be defined. ```clojure ;; Boolean aggregates (pack variables with +) (solve (qdsl {} {"a" [:boolean] "b" [:boolean] "c" [:boolean]} [add-bool-or (+ "a" "b" "c")] ; at least one is true [!= "b" "c"] ; b != c {:enumerate-all true}) ;; => [{"a" 0, "b" 0, "c" 1} {"a" 1, "b" 0, "c" 1} ...] ``` -------------------------------- ### Scoped Variables with `$` and `$#` for Reusable Functions Source: https://context7.com/mlimotte/quandary/llms.txt Demonstrates using `$` for constructing dotted names (e.g., `"kitchen.width"`) and `$#` for creating hidden temporary variables within reusable constraint functions. This prevents name collisions. ```clojure (require '[quandary.api :refer [solve qdsl collate $ $#]]) ;; $ constructs dotted names: ($ "kitchen" "width") => "kitchen.width" ;; $# creates hidden temp vars: ($# "kitchen" "temp") => "TEMP.kitchen.temp" (defn rectangle-area [prefix area-bound] (qdsl {} {($ prefix "width") [:range 1 100] ($ prefix "height") [:range 1 100] ($# prefix "area") [:range 1 10000]} ; temp var hidden from output [= ($# prefix "area") (* ($ prefix "width") ($ prefix "height"))] [<= ($# prefix "area") area-bound])) (solve (collate (rectangle-area "box1" 500) (rectangle-area "box2" 300)) {:limit 1}) ;; Returns only: {"box1.width" X, "box1.height" Y, "box2.width" ...} ;; Temp vars like "TEMP.box1.area" are excluded from results ``` -------------------------------- ### Runtime Evaluation in Equations Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Other Clojure expressions in argument position are evaluated normally at runtime. Use functions like `inc`, `dec`, `quot`, or `Math/abs` to compute constant values before they enter the solver. ```clojure (let [n 9] (qdsl {} {"answer" [:range 0 100]} ;; `inc` is clojure.core/inc and is evaluated before the result is embedded in the equation [= "answer" (inc n)])) ``` -------------------------------- ### Boolean Implication Constraint in Quandary Source: https://context7.com/mlimotte/quandary/llms.txt Shows how to define a boolean implication constraint (a => b), meaning if 'a' is true, 'b' must also be true. Requires boolean variables to be defined. ```clojure ;; Boolean implication: a => b (if a is true, b must be true) (solve (qdsl {} {"a" [:boolean] "b" [:boolean]} [=> "a" "b"] [= "a" 1]) {:enumerate-all true}) ;; => [{"a" 1, "b" 1}] ``` -------------------------------- ### solve Source: https://context7.com/mlimotte/quandary/llms.txt The primary function to solve a constraint problem defined by a DSL map. ```APIDOC ## solve ### Description Executes the constraint solver on a problem definition created by `qdsl` or `collate`. ### Parameters - **problem** (map) - Required - The problem definition containing domains and equations. - **options** (map) - Optional - Configuration options such as {:enumerate-all true} or {:limit n}. ### Request Example (solve (qdsl {} {"x" [:range 0 100]} [= "x" 10]) {:limit 1}) ### Response - **result** (vector of maps) - A collection of variable assignments that satisfy the constraints. ``` -------------------------------- ### Define optional fixed-size interval domain Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Defines an optional scheduling interval for 'task2' with a fixed size of 3. The interval is present only if the 't2.present' variable is set to 1. ```clojure "task2" [:optional-fixed-size-interval "t2.start" "t2.present" 3] ``` -------------------------------- ### Domain Specifications Source: https://context7.com/mlimotte/quandary/llms.txt Domain maps define the possible values for each variable. Quandary supports various domain types including ranges, booleans, fixed constants, enumerations, intervals, and tuple constraints. ```APIDOC ## Domain Specifications ### Description Domain maps define the possible values for each variable. Multiple domain types are supported including ranges, booleans, fixed constants, enumerations, intervals, and tuple constraints. ### Method N/A (Part of `qdsl` macro) ### Endpoint N/A ### Parameters #### Domain Types - **[:range min max]** - Integer in [min, max] inclusive. - **[:boolean]** - Boolean (0 or 1). - **[constant]** - Fixed constant value. - **[val1 val2 ...]** - Enumerated values; variable must be one of these. - **[:fixed-size-interval start_var size]** - A fixed-size interval anchored at `start_var` with a given `size`. - **[:optional-fixed-size-interval start_var present_var size]** - An interval that is present only if `present_var` is true (1). - **[:tuples [[val1 val2 ...] [val3 val4 ...]]]** - A tuple constraint where the variable tuple must match one of the provided tuples. ### Request Example ```clojure (require '[quandary.api :refer [qdsl]]) ;; All domain specification types (qdsl {} {"x" [:range 0 20] ; integer in [0, 20] inclusive "flag" [:boolean] ; 0 or 1 "size" [5] ; fixed constant: always 5 "color" [1 2 3 4] ; enumerated: one of these values ;; Fixed-size interval for scheduling (anchored at task.start) "task.start" [:range 0 100] "task" [:fixed-size-interval "task.start" 5] ;; Optional interval (present only if t2.present=1) "t2.start" [:range 0 100] "t2.present" [:boolean] "task2" [:optional-fixed-size-interval "t2.start" "t2.present" 3] ;; Tuple constraint: (a=1,b=2) or (a=3,b=4) are the only allowed ["a" "b"] [:tuples [[1 2] [3 4]]]} ;; equations here... ) ``` ### Response N/A (This section describes input domain specifications, not direct responses. ``` -------------------------------- ### Apply Conditional Constraints with :only-enforce-if Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Conditionally apply constraints based on a boolean variable. The :only-enforce-else branch is optional. ```clojure (qdsl {} {"mode" [:boolean] "x" [:range 0 100] "y" [:range 0 100]} [:only-enforce-if "mode" [= "x" 10] [= "y" 20] [<= "x" "y"] :only-enforce-else [= "x" 50] [= "y" 50]]) ``` ```clojure (qdsl {} {"active" [:boolean] "x" [:range 0 100]} [:only-enforce-if "active" [= "x" 42] [<= "x" 50]]) ;; When active=0, x is unconstrained within [0, 100] ``` -------------------------------- ### Quandary Domain Specification Types Source: https://context7.com/mlimotte/quandary/llms.txt Quandary supports various domain specifications for variables, including ranges, booleans, fixed constants, enumerations, and interval types. Tuple constraints can also be defined. ```clojure (require '[quandary.api :refer [qdsl]]) ;; All domain specification types (qdsl {} ({"x" [:range 0 20] ; integer in [0, 20] inclusive "flag" [:boolean] ; 0 or 1 "size" [5] ; fixed constant: always 5 "color" [1 2 3 4] ; enumerated: one of these values ;; Fixed-size interval for scheduling (anchored at task.start) "task.start" [:range 0 100] "task" [:fixed-size-interval "task.start" 5] ;; Optional interval (present only if t2.present=1) "t2.start" [:range 0 100] "t2.present" [:boolean] "task2" [:optional-fixed-size-interval "t2.start" "t2.present" 3] ;; Tuple constraint: (a=1,b=2) or (a=3,b=4) are the only allowed ["a" "b"] [:tuples [[1 2] [3 4]]]}) ;; equations here... ) ``` -------------------------------- ### Define integer range domain Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Specifies an integer variable 'x' that can take any value within the inclusive range [0, 20]. ```clojure {"x" [:range 0 20]} ``` -------------------------------- ### collate Source: https://context7.com/mlimotte/quandary/llms.txt Merges multiple problem definitions into a single problem. ```APIDOC ## collate ### Description Combines multiple `qdsl` problem maps into one, allowing for modular constraint definition. ### Parameters - **problems** (varargs) - Required - Multiple problem maps to be merged. ### Request Example (collate (qdsl ...) (qdsl ...)) ``` -------------------------------- ### collate Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Merges multiple problem maps into a single problem definition. ```APIDOC ## collate ### Description Merges multiple {:domain ..., :equations ...} maps into one problem. Equations are concatenated and domain entries are merged. Duplicate variable names across maps will throw an error. ### Usage (collate & maps) ### Example (solve (collate (qdsl {} {"x" [:range 0 10]} [= "x" 5]) (qdsl {} {"y" [:range 0 10]} [= "y" (* 2 "x")]))) ``` -------------------------------- ### Variable Scoping ($ and $#) Source: https://context7.com/mlimotte/quandary/llms.txt Utilities for creating unique or hidden variable names. ```APIDOC ## $ and $# ### Description `$` creates namespaced variable names (e.g., "prefix.name"). `$#` creates temporary variables that are excluded from the final solver output. ### Parameters - **prefix** (string) - Required - The namespace prefix. - **name** (string) - Required - The variable identifier. ### Request Example ($ "room1" "width") ;; => "room1.width" ($# "room1" "temp") ;; => "TEMP.room1.temp" ``` -------------------------------- ### Combine problems with collate Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Merges multiple problem maps into one. Duplicate variable names across domains will trigger an error. ```clojure (require '[quandary.api :refer [solve qdsl collate]]) (solve (collate (qdsl {} {"x" [:range 0 10]} [= "x" 5]) (qdsl {} {"y" [:range 0 10]} [= "y" (* 2 "x")]))) ``` -------------------------------- ### Construct Unique Variable Names with $ Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Use the $ operator to generate unique variable names by prefixing them, preventing collisions when reusing functions. ```clojure (defn room-constraints [room-name max-perimeter] (qdsl {} {($ room-name "width") [:range 1 500] ($ room-name "height") [:range 1 500]} [<= (+ ($ room-name "width") ($ room-name "height")) max-perimeter])) (solve (collate (room-constraints "kitchen" 100) (room-constraints "bedroom" 80))) ;; Variables: "kitchen.width", "kitchen.height", "bedroom.width", "bedroom.height" ``` -------------------------------- ### Define fixed constant domain Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Assigns a variable 'size' to a fixed constant value of 5. ```clojure "size" [5] ``` -------------------------------- ### Boolean Aggregate Usage in qdsl Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Boolean aggregate functions like add-bool-or, add-bool-and, and add-bool-xor require a single polynomial argument containing all participating variables, packed with '+'. Listing variables as separate arguments will cause an arity error. ```clojure [add-bool-or (+ "a" "b" "c")] ``` ```clojure [add-bool-and (+ "x" "y")] ``` -------------------------------- ### Arithmetic in Equations Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Use Clojure arithmetic s-expressions like +, -, and * within equation vectors. These are recognized by the macro and expanded into the internal polynomial format. For constant computations before solving, use other Clojure functions. ```clojure [= (+ "x" (* 2 "y")) 10] ``` ```clojure [= (- "a" "b") 0] ``` ```clojure [= (* "a" "b") "c"] ``` -------------------------------- ### Calculate Floor Square Root Source: https://context7.com/mlimotte/quandary/llms.txt Constrains a target variable to the floor of the square root of an input variable. ```clojure (require '[quandary.api :refer [solve collate qdsl]] '[quandary.relations :refer [sqrto]]) ;; Find floor(sqrt(x)) where x = 50 (solve (collate (qdsl {} {"x" [50] "root" [:range 0 100]}) (sqrto "root" "x" 100)) ; target, input, upper-bound {:limit 1}) ;; => [{"x" 50, "root" 7}] ; floor(sqrt(50)) = 7 ``` -------------------------------- ### Define enumerated domain Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Specifies a variable 'color' that can only take one of the enumerated values: 1, 2, 3, or 4. ```clojure "color" [1 2 3 4] ``` -------------------------------- ### Apply 2D Non-Overlap Constraints Source: https://context7.com/mlimotte/quandary/llms.txt Ensures rectangles do not overlap in 2D space using the no-overlap-2d constraint. ```clojure (require '[quandary.api :refer [solve qdsl]]) ;; Place two non-overlapping rectangles in a grid (solve (qdsl {} ;; Rectangle 1: x-interval and y-interval {"r1.x.start" [:range 0 100] "r1.x" [:fixed-size-interval "r1.x.start" 10] "r1.y.start" [:range 0 100] "r1.y" [:fixed-size-interval "r1.y.start" 20] ;; Rectangle 2 "r2.x.start" [:range 0 100] "r2.x" [:fixed-size-interval "r2.x.start" 15] "r2.y.start" [:range 0 100] "r2.y" [:fixed-size-interval "r2.y.start" 25]} ;; Rectangles cannot overlap [no-overlap-2d [["r1.x" "r1.y"] ["r2.x" "r2.y"]]]) {:limit 1}) ``` -------------------------------- ### Define tuple domain constraint Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Applies a tuple constraint to variables 'a' and 'b', restricting their possible assignments to either (a=1, b=2) or (a=3, b=4). ```clojure ["a" "b"] [:tuples [[1 2] [3 4]]] ``` -------------------------------- ### Define boolean domain Source: https://github.com/mlimotte/quandary/blob/main/docs/dsl.md Specifies a boolean variable 'flag' which can be either 0 or 1. ```clojure "flag" [:boolean] ``` -------------------------------- ### Conditional Constraints without `:only-enforce-else` Source: https://context7.com/mlimotte/quandary/llms.txt Illustrates that when `:only-enforce-else` is omitted, variables remain unconstrained when the `:only-enforce-if` condition is false. This allows for flexibility in problem definitions. ```clojure ;; Without else clause: unconstrained when condition is false (solve (qdsl {} {"active" [:boolean] "x" [:range 0 10]} [= "active" 0] [:only-enforce-if "active" [= "x" 5]]) ; when active=0, x can be any value in [0, 10] {:enumerate-all true}) ;; => [{"active" 0, "x" 0} {"active" 0, "x" 1} ... {"active" 0, "x" 10}] ``` -------------------------------- ### Check Range Membership Source: https://context7.com/mlimotte/quandary/llms.txt Sets a boolean target to true if a point is strictly inside an open interval. ```clojure (require '[quandary.api :refer [solve collate qdsl]] '[quandary.relations :refer [is-exclusive-betweeno]]) ;; Check if pt is strictly between start and stop (solve (collate (qdsl {} {"pt" [:range 0 100] "start" [10] "stop" [20] "is-inside" [:boolean]}) (is-exclusive-betweeno "pt" "start" "stop" "is-inside")) {:enumerate-all true :limit 5}) ;; When pt is in (10, 20) exclusive, is-inside = 1 ;; When pt <= 10 or pt >= 20, is-inside = 0 ``` -------------------------------- ### Calculate Ceiling Division Source: https://context7.com/mlimotte/quandary/llms.txt Constrains a target variable to the ceiling of the division of two variables. ```clojure (require '[quandary.api :refer [solve collate qdsl]] '[quandary.relations :refer [ceil-div-o]]) ;; Ceiling division: ceil(17 / 5) = 4 (solve (collate (qdsl {} {"x" [17] "y" [5] "result" [:range 0 100]}) (ceil-div-o "result" "x" "y")) {:limit 1}) ;; => [{"x" 17, "y" 5, "result" 4}] ``` -------------------------------- ### Calculate Statistical Variance Source: https://context7.com/mlimotte/quandary/llms.txt Computes the variance of a set of terms. ```clojure (require '[quandary.api :refer [solve collate qdsl]] '[quandary.relations :refer [variance]]) ;; Calculate variance of variables (solve (collate (qdsl {} {"a" [10] "b" [20] "c" [30] "var" [:range 0 1000]}) (variance "var" ["a" "b" "c"] 0 1000)) {:limit 1}) ;; Variance of [10, 20, 30] = ((10-20)^2 + (20-20)^2 + (30-20)^2) / 3 = 66 ``` -------------------------------- ### Calculate Mean of Variables Source: https://context7.com/mlimotte/quandary/llms.txt Computes the average of a set of variables using the mean relation. ```clojure (require '[quandary.api :refer [solve collate qdsl]] '[quandary.relations :refer [mean]]) ;; Calculate mean of three variables (solve (collate (qdsl {} {"a" [:range 10 20] "b" [:range 20 30] "c" [:range 30 40] "avg" [:range 0 100]} [= "a" 15] [= "b" 25] [= "c" 35]) (mean "avg" ["a" "b" "c"] 0 100)) {:limit 1}) ;; => [{"a" 15, "b" 25, "c" 35, "avg" 25}] ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.