grilops
Version:
A Grid Logic Puzzle Solver library, using Typescript and z3.
16 lines (15 loc) • 36.3 kB
JavaScript
"use strict";var _t=Object.defineProperty;var pt=(r,i,e)=>i in r?_t(r,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[i]=e;var a=(r,i,e)=>(pt(r,typeof i!="symbol"?i+"":i,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ut=require("z3-solver");function B(...r){const i=Math.min(...r.map(e=>e.length));return Array.from({length:i},(e,t)=>r.map(s=>s[t]))}function*N(r,i){if(i===0)yield[];else for(let e=0;e<r.length;e++){const t=r[e];for(const s of N(r.slice(e+1),i-1))yield[t,...s]}}function k(r){return class extends r{constructor(t,s){super(s);a(this,"default");this.default=t}get(t){return this.has(t)||this.set(t,this.default()),super.get(t)}}}function v(r,i){return class extends Map{get(t){return super.get(r(t))}has(t){return super.has(r(t))}set(t,s){return super.set(r(t),s)}delete(t){return super.delete(r(t))}forEach(t,s){super.forEach((n,o,h)=>t(n,i(o),h),s)}*[Symbol.iterator](){for(const[t,s]of super[Symbol.iterator]())yield[i(t),s]}constructor(t){super([...t??[]].map(([s,n])=>[r(s),n]))}}}function L(r,i){return class extends Set{has(t){return super.has(r(t))}add(t){return super.add(r(t))}delete(t){return super.delete(r(t))}forEach(t,s){super.forEach((n,o,h)=>t(i(n),i(o),h),s)}*[Symbol.iterator](){for(const t of super[Symbol.iterator]())yield i(t)}constructor(t){super([...t??[]].map(s=>r(s)))}}}class d{constructor(i,e){a(this,"dy");a(this,"dx");this.dy=i,this.dx=e}negate(){return new d(-this.dy,-this.dx)}translate(i){return new d(this.dy+i.dy,this.dx+i.dx)}toString(){return`V(${this.dy},${this.dx})`}static fromString(i){const e=i.match(/^V\((\d+),(\d+)\)$/);if(e===null)throw new Error(`Invalid VectorString: ${i}`);return new d(parseInt(e[1]),parseInt(e[2]))}equals(i){return this.dy===i.dy&&this.dx===i.dx}static comparator(i,e){return i.dy<e.dy?-1:i.dy>e.dy?1:i.dx<e.dx?-1:i.dx>e.dx?1:0}}const Y=v(r=>r.toString(),d.fromString),tt=L(r=>r.toString(),d.fromString),et=k(Y);class p{constructor(i,e){a(this,"name");a(this,"vector");this.name=i,this.vector=e}toString(){return`D(${this.name},${this.vector.toString()})`}static fromString(i){const e=i.match(/^D\((\w+),(V\(\d+,\d+\))\)$/);if(e===null)throw new Error(`Invalid DirectionString: ${i}`);return new p(e[1],d.fromString(e[2]))}}const P=v(r=>r.toString(),p.fromString),it=L(r=>r.toString(),p.fromString),H=k(P);class m{constructor(i,e){a(this,"y");a(this,"x");this.y=i,this.x=e}translate(i){return i instanceof p&&(i=i.vector),new m(this.y+i.dy,this.x+i.dx)}toString(){return`P(${this.y},${this.x})`}static fromString(i){const e=i.match(/^P\((\d+),(\d+)\)$/);if(e===null)throw new Error(`Invalid PointString: ${i}`);return new m(parseInt(e[1]),parseInt(e[2]))}equals(i){return this.y===i.y&&this.x===i.x}static comparator(i,e){return i.y<e.y?-1:i.y>e.y?1:i.x<e.x?-1:i.x>e.x?1:0}}const g=v(r=>r.toString(),m.fromString),U=L(r=>r.toString(),m.fromString),Q=k(g);class Z{constructor(i,e,t){a(this,"location");a(this,"direction");a(this,"symbol");this.location=i,this.direction=e,this.symbol=t}}class b{constructor(){a(this,"_vectorDirection");this._vectorDirection=new Y;for(const i of this.vertexSharingDirections())this._vectorDirection.set(i.vector,i)}oppositeDirection(i){return this._vectorDirection.get(i.vector.negate())}edgeSharingPoints(i){return this.edgeSharingDirections().map(e=>i.translate(e))}vertexSharingPoints(i){return this.vertexSharingDirections().map(e=>i.translate(e))}static _getNeighbors(i,e,t){const s=[];for(const n of t){const o=e.translate(n),h=i.get(o);h!==void 0&&s.push(new Z(o,n,h))}return s}edgeSharingNeighbors(i,e){return b._getNeighbors(i,e,this.edgeSharingDirections())}vertexSharingNeighbors(i,e){return b._getNeighbors(i,e,this.vertexSharingDirections())}_pointsToString(i,e,t=" "){const s=[];for(const n of e){let o;this.pointToIndex(n)!==void 0&&(o=i(n)),o=o??t,s.push(o.split(`
`))}return B(...s).map(n=>n.join("")).join(`
`)+`
`}toString(i,e=" "){let t="";const s=this.points,n=s[0].y,o=s[s.length-1].y,h=Math.min(...s.map(l=>l.x)),c=Math.max(...s.map(l=>l.x));for(let l=n;l<=o;l++)t+=this._pointsToString(i,Array.from({length:c-h+1},(u,_)=>new m(l,_+h)),e);return t}}const y=class y extends b{constructor(e){super();a(this,"_points");a(this,"_pointIndices");this._points=e.sort(m.comparator),this._pointIndices=new g,this._points.forEach((t,s)=>{this._pointIndices.set(t,s)})}get points(){return this._points}pointToIndex(e){return this._pointIndices.get(e)}edgeSharingDirections(){return Object.values(y.EDGE_DIRECTIONS)}vertexSharingDirections(){return Object.values(y.VERTEX_DIRECTIONS)}labelForDirection(e){if(e.name==="N")return"╵";if(e.name==="E")return"╶";if(e.name==="S")return"╷";if(e.name==="W")return"╴";throw new Error("No single-character symbol for direction")}labelForDirectionPair(e,t){if(e.name==="N"&&t.name==="S")return"│";if(e.name==="E"&&t.name==="W")return"─";if(e.name==="N"&&t.name==="E")return"└";if(e.name==="S"&&t.name==="E")return"┌";if(e.name==="S"&&t.name==="W")return"┐";if(e.name==="N"&&t.name==="W")return"┘";throw new Error("No single-character symbol for direction pair")}transformationFunctions(e,t){return e?t?[s=>s,s=>new d(s.dy,-s.dx),s=>new d(-s.dy,s.dx),s=>new d(-s.dy,-s.dx),s=>new d(s.dx,s.dy),s=>new d(s.dx,-s.dy),s=>new d(-s.dx,s.dy),s=>new d(-s.dx,-s.dy)]:[s=>s,s=>new d(s.dx,-s.dy),s=>new d(-s.dy,-s.dx),s=>new d(-s.dx,s.dy)]:t?[s=>s,s=>new d(s.dy,-s.dx),s=>new d(-s.dy,s.dx)]:[s=>s]}getInsideOutsideCheckDirections(){const e=this.edgeSharingDirections();return[e.find(t=>t.name==="N"),[e.find(t=>t.name==="W")]]}};a(y,"EDGE_DIRECTIONS",{N:new p("N",new d(-1,0)),S:new p("S",new d(1,0)),E:new p("E",new d(0,1)),W:new p("W",new d(0,-1))}),a(y,"VERTEX_DIRECTIONS",{...y.EDGE_DIRECTIONS,NE:new p("NE",new d(-1,1)),NW:new p("NW",new d(-1,-1)),SE:new p("SE",new d(1,1)),SW:new p("SW",new d(1,-1))});let E=y;const R=class R extends b{constructor(e){super();a(this,"_points");a(this,"_pointIndices");for(const t of e)if((t.y+t.x)%2===1)throw new Error("Hexagonal coordinates must have an even sum.");this._points=e.sort(m.comparator),this._pointIndices=new g,this._points.forEach((t,s)=>{this._pointIndices.set(t,s)})}get points(){return this._points}pointToIndex(e){return this._pointIndices.get(e)}vertexSharingDirections(){return this.edgeSharingDirections()}labelForDirection(e){const t=R._DIRECTION_LABELS[e.name];if(t!==void 0)return t;throw new Error("No single-character symbol for direction")}labelForDirectionPair(e,t){let s=[e.name,t.name];function n(u,_){for(const[x,ct]of B(u,_))if(s.includes(x))return s=s.filter(lt=>lt!==x),ct.toString();return" "}const o=n(["NW","N","W"],["╲","▕","▁"]),h=n(["NE","N","E"],["╱","▏","▁"]),c=n(["SW","S","W"],["╱","▕","▔"]),l=n(["SE","S","E"],["╲","▏","▔"]);return`${o}${h}
${c}${l}`}};a(R,"_DIRECTION_LABELS",{N:`▕
`,NE:` ╱
`,E:` ▁
`,SE:`
╲`,S:`
▕ `,SW:`
╱ `,W:`▁
`,NW:`╲
`});let G=R;const V=class V extends G{edgeSharingDirections(){return Object.values(V.DIRECTIONS)}transformationFunctions(i,e){return i?e?[t=>t,t=>new d((t.dy+3*t.dx)/2,(-t.dy+t.dx)/2),t=>new d((-t.dy+3*t.dx)/2,(-t.dy-t.dx)/2),t=>new d(-t.dy,-t.dx),t=>new d((-t.dy-3*t.dx)/2,(t.dy-t.dx)/2),t=>new d((t.dy-3*t.dx)/2,(t.dy+t.dx)/2),t=>new d(-t.dy,t.dx),t=>new d((-t.dy-3*t.dx)/2,(-t.dy+t.dx)/2),t=>new d((t.dy-3*t.dx)/2,(-t.dy-t.dx)/2),t=>new d(t.dy,-t.dx),t=>new d((t.dy+3*t.dx)/2,(t.dy-t.dx)/2),t=>new d((-t.dy+3*t.dx)/2,(t.dy+t.dx)/2)]:[t=>t,t=>new d((t.dy+3*t.dx)/2,(-t.dy+t.dx)/2),t=>new d((-t.dy+3*t.dx)/2,(-t.dy-t.dx)/2),t=>new d(-t.dy,-t.dx),t=>new d((-t.dy-3*t.dx)/2,(t.dy-t.dx)/2),t=>new d((t.dy-3*t.dx)/2,(t.dy+t.dx)/2)]:e?[t=>t,t=>new d(-t.dy,t.dx),t=>new d((-t.dy-3*t.dx)/2,(-t.dy+t.dx)/2),t=>new d((t.dy-3*t.dx)/2,(-t.dy-t.dx)/2),t=>new d(t.dy,-t.dx),t=>new d((t.dy+3*t.dx)/2,(t.dy-t.dx)/2),t=>new d((-t.dy+3*t.dx)/2,(t.dy+t.dx)/2)]:[t=>t]}getInsideOutsideCheckDirections(){const i=this.edgeSharingDirections();return[i.find(e=>e.name==="N"),[i.find(e=>e.name==="NW"),i.find(e=>e.name==="SW")]]}};a(V,"DIRECTIONS",{N:new p("N",new d(-2,0)),S:new p("S",new d(2,0)),NE:new p("NE",new d(-1,1)),NW:new p("NW",new d(-1,-1)),SE:new p("SE",new d(1,1)),SW:new p("SW",new d(1,-1))});let O=V;const j=class j extends G{edgeSharingDirections(){return Object.values(j.DIRECTIONS)}transformationFunctions(i,e){return i?e?[t=>t,t=>new d((t.dy+t.dx)/2,(-3*t.dy+t.dx)/2),t=>new d((-t.dy+t.dx)/2,(-3*t.dy-t.dx)/2),t=>new d(-t.dy,-t.dx),t=>new d((-t.dy-t.dx)/2,(3*t.dy-t.dx)/2),t=>new d((t.dy-t.dx)/2,(3*t.dy+t.dx)/2),t=>new d(-t.dy,t.dx),t=>new d((-t.dy-t.dx)/2,(-3*t.dy+t.dx)/2),t=>new d((t.dy-t.dx)/2,(-3*t.dy-t.dx)/2),t=>new d(t.dy,-t.dx),t=>new d((t.dy+t.dx)/2,(3*t.dy-t.dx)/2),t=>new d((-t.dy+t.dx)/2,(3*t.dy+t.dx)/2)]:[t=>t,t=>new d((t.dy+t.dx)/2,(-3*t.dy+t.dx)/2),t=>new d((-t.dy+t.dx)/2,(-3*t.dy-t.dx)/2),t=>new d(-t.dy,-t.dx),t=>new d((-t.dy-t.dx)/2,(3*t.dy-t.dx)/2),t=>new d((t.dy-t.dx)/2,(3*t.dy+t.dx)/2)]:e?[t=>new d(-t.dy,t.dx),t=>new d((-t.dy-t.dx)/2,(-3*t.dy+t.dx)/2),t=>new d((t.dy-t.dx)/2,(-3*t.dy-t.dx)/2),t=>new d(t.dy,-t.dx),t=>new d((t.dy+t.dx)/2,(3*t.dy-t.dx)/2),t=>new d((-t.dy+t.dx)/2,(3*t.dy+t.dx)/2)]:[t=>t]}getInsideOutsideCheckDirections(){const i=this.edgeSharingDirections();return[i.find(e=>e.name==="E"),[i.find(e=>e.name==="NW"),i.find(e=>e.name==="NE")]]}};a(j,"DIRECTIONS",{E:new p("E",new d(0,2)),W:new p("W",new d(0,-2)),NE:new p("NE",new d(-1,1)),NW:new p("NW",new d(-1,-1)),SE:new p("SE",new d(1,1)),SW:new p("SW",new d(1,-1))});let C=j;function J(r,i){const e=[];for(let t=0;t<r;t++)for(let s=0;s<i;s++)e.push(new m(t,s));return new E(e)}function st(r){return J(r,r)}const xt=Object.freeze(Object.defineProperty({__proto__:null,DefaultDirectionMap:H,DefaultPointMap:Q,DefaultVectorMap:et,Direction:p,DirectionMap:P,DirectionSet:it,FlatToppedHexagonalLattice:O,HexagonalLattice:G,Lattice:b,Neighbor:Z,Point:m,PointMap:g,PointSet:U,PointyToppedHexagonalLattice:C,RectangularLattice:E,Vector:d,VectorMap:Y,VectorSet:tt,getRectangleLattice:J,getSquareLattice:st},Symbol.toStringTag,{value:"Module"})),X=class X{constructor(i,e,t,s=void 0){a(this,"ctx");a(this,"_lattice");a(this,"_symbolSet");a(this,"_solver");a(this,"_grid");this.ctx=i,this._lattice=e,this._symbolSet=t,this._solver=s??new this.ctx.context.Solver,this._grid=new g;for(const n of e.points){const o=this.ctx.context.Int.const(`sg_${X._instanceIndex}_${n.y}-${n.x}`);this._solver.add(o.ge(t.minIndex()),o.le(t.maxIndex())),this._grid.set(n,o)}}get solver(){return this._solver}get symbolSet(){return this._symbolSet}get grid(){return this._grid}get lattice(){return this._lattice}edgeSharingNeighbors(i){return this._lattice.edgeSharingNeighbors(this._grid,i)}vertexSharingNeighbors(i){return this._lattice.vertexSharingNeighbors(this._grid,i)}cellAt(i){return this._grid.get(i)}cellIs(i,e){return this._grid.get(i).eq(e)}cellIsOneOf(i,e){const t=this._grid.get(i);return this.ctx.context.Or(...e.map(s=>t.eq(s)))}async solve(){return await this._solver.check()==="sat"}async isUnique(){const i=this._solver.model(),e=[];for(const t of this._grid.values())e.push(t.neq(i.eval(t)));return this._solver.add(this.ctx.context.Or(...e)),await this._solver.check()==="unsat"}solvedGrid(){const i=this._solver.model(),e=new g;for(const[t,s]of this._grid.entries())e.set(t,Number(i.eval(s)));return e}toString(i){const e=this._solver.model(),t=Math.max(...[...this.symbolSet.symbols.values()].map(n=>n.label.length)),s=n=>{var l;const o=this._grid.get(n),h=Number(e.eval(o));let c;return i&&(c=i(n,h)),c===void 0&&(c=(l=this.symbolSet.symbols.get(h))==null?void 0:l.label.padStart(t)),c};return this._lattice.toString(s," ".repeat(t))}};a(X,"_instanceIndex",0);let z=X;function gt(r){return{SymbolGrid:function(i,e,t=void 0){return new z(r,i,e,t)}}}class M{constructor(i,e,t){a(this,"ctx");a(this,"_exprs",new Map);a(this,"_exprFuncs");a(this,"_point");a(this,"_yMin",Number.NaN);a(this,"_yMax",Number.NaN);a(this,"_xMin",Number.NaN);a(this,"_xMax",Number.NaN);a(this,"_yMid",Number.NaN);a(this,"_xMid",Number.NaN);a(this,"_tl");a(this,"_tr");a(this,"_bl");a(this,"_br");a(this,"_quads",[]);if(this.ctx=i,e.length===0)throw new Error("A quadtree node must be constructed with at least one point");if(this._exprFuncs=t??new Map,this._point=e.length===1?e[0]:void 0,!this._point){this._yMin=Math.min(...e.map(n=>n.y)),this._yMax=Math.max(...e.map(n=>n.y)),this._xMin=Math.min(...e.map(n=>n.x)),this._xMax=Math.max(...e.map(n=>n.x)),this._yMid=(this._yMin+this._yMax)/2,this._xMid=(this._xMin+this._xMax)/2;const s=n=>{const o=e.filter(n);if(o.length>0)return new M(this.ctx,o,this._exprFuncs)};this._tl=s(n=>n.y<this._yMid&&n.x<this._xMid),this._tr=s(n=>n.y<this._yMid&&n.x>=this._xMid),this._bl=s(n=>n.y>=this._yMid&&n.x<this._xMid),this._br=s(n=>n.y>=this._yMid&&n.x>=this._xMid),this._quads=[this._tl,this._tr,this._bl,this._br].filter(Boolean)}}coversPoint(i){return this._point?this._point.equals(i):i.y>=this._yMin&&i.y<=this._yMax&&i.x>=this._xMin&&i.x<=this._xMax}addExpr(i,e){this._exprFuncs.set(i,e)}getExprs(i){if(this._point){let e=this._exprs.get(i);return e||(e=this._exprFuncs.get(i)(this._point),this._exprs.set(i,e)),[e]}return this._quads.flatMap(e=>e.getExprs(i))}getPointExpr(i,e){if(this._point){if(this._point.equals(e)){let t=this._exprs.get(i);return t||(t=this._exprFuncs.get(i)(this._point),this._exprs.set(i,t)),t}throw new Error(`Point ${e.toString()} not in QuadTree`)}if(this._tl&&e.y<this._yMid&&e.x<this._xMid)return this._tl.getPointExpr(i,e);if(this._tr&&e.y<this._yMid&&e.x>=this._xMid)return this._tr.getPointExpr(i,e);if(this._bl&&e.y>=this._yMid&&e.x<this._xMid)return this._bl.getPointExpr(i,e);if(this._br&&e.y>=this._yMid&&e.x>=this._xMid)return this._br.getPointExpr(i,e);throw new Error(`Point ${e.toString()} not in QuadTree`)}getOtherPointsExpr(i,e){if(this._point)return e.some(n=>this._point.equals(n))?void 0:this.getPointExpr(i,this._point);const t=e.filter(n=>this.coversPoint(n));if(t.length>0){const n=this._quads.map(o=>o.getOtherPointsExpr(i,t)).filter(Boolean);return this.ctx.context.And(...n)}let s=this._exprs.get(i);return s||(s=this.ctx.context.And(...this.getExprs(i)),this._exprs.set(i,s)),s}}function mt(r){return{ExpressionQuadTree:function(i,e){return new M(r,i,e)}}}let T=class{constructor(i,e,t){a(this,"_index");a(this,"_name");a(this,"_label");this._index=i,this._name=e,this._label=t}get index(){return this._index}get name(){return this._name??this._label??this._index.toString()}get label(){return this._label??this._name??this._index.toString()}toString(){return this.label}};class q{constructor(i){a(this,"_indexToSymbol",new Map);a(this,"_labelToSymbolIndex",new Map);a(this,"indices",{});var e;for(const t of i)if(typeof t=="string"){const s=this._nextUnusedIndex();this._indexToSymbol.set(s,new T(s,t))}else if(Array.isArray(t)){let[s,n,o]=t;if(t.length===3){if(this._indexToSymbol.has(o))throw new Error(`Index of ${t.toString()} already used by ${(e=this._indexToSymbol.get(o))==null?void 0:e.toString()}`)}else if(t.length===2)o=this._nextUnusedIndex();else throw new Error(`Invalid symbol spec: ${t.toString()}`);this._indexToSymbol.set(o,new T(o,s,n))}else throw new Error(`Invalid symbol spec: ${t.toString()}`);for(const t of this._indexToSymbol.values())this.indices[t.name]=t.index,this._labelToSymbolIndex.set(t.label,t.index)}_nextUnusedIndex(){return this._indexToSymbol.size===0?0:Math.max(...this._indexToSymbol.keys())+1}append(i=void 0,e=void 0){const t=this._nextUnusedIndex(),s=new T(t,i,e);this._indexToSymbol.set(t,s),this.indices[s.name]=s.index,this._labelToSymbolIndex.set(s.label,s.index)}minIndex(){return Math.min(...this._indexToSymbol.keys())}maxIndex(){return Math.max(...this._indexToSymbol.keys())}get symbols(){return this._indexToSymbol}toString(){return`SymbolSet(${[...this._indexToSymbol.values()].join(", ")})`}}function nt(r,i){const e=[];for(let t=r.charCodeAt(0);t<=i.charCodeAt(0);t++)e.push(String.fromCharCode(t));return new q(e)}function rt(r,i){const e=[];for(let t=r;t<=i;t++)e.push(["S"+t.toString(),t.toString(),t]);return new q(e)}const ft=Object.freeze(Object.defineProperty({__proto__:null,Symbol:T,SymbolSet:q,makeLetterRangeSymbolSet:nt,makeNumberRangeSymbolSet:rt},Symbol.toStringTag,{value:"Module"}));function K(r,i,e,t,s,n,o=()=>r.context.Bool.val(!1)){const h=[],c=[s];let l=e;for(;i.grid.has(l);){const _=i.grid.get(l),x=n(c[c.length-1],_,l);c.push(x),h.push(o(x,_,l)),l=l.translate(t.vector)}let u=c.pop();for(const[_,x]of B(h.reverse(),c.reverse()))u=r.context.If(_,x,u);return u}function ot(r,i,e,t,s=o=>r.context.Int.val(1),n=o=>r.context.Bool.val(!1)){return K(r,i,e,t,r.context.Int.val(0),(o,h)=>o.add(s(h)),(o,h)=>n(h))}function yt(r){return{reduceCells:(i,e,t,s,n,o=()=>r.context.Bool.val(!1))=>K(r,i,e,t,s,n,o),countCells:(i,e,t,s=o=>r.context.Int.val(1),n=o=>r.context.Bool.val(!1))=>ot(r,i,e,t,s,n)}}function at(r){if(r.z3.get_error_code(r.context.ptr)!==ut.Z3_error_code.Z3_OK)throw new Error(r.z3.get_error_msg(r.context.ptr,r.z3.get_error_code(r.context.ptr)))}function St(r,i){return at(r),i}function bt(r,i,e){i.__typename==="Solver"?r.z3.solver_assert(r.context.ptr,i.ptr,e):r.z3.optimize_assert(r.context.ptr,i.ptr,e),at(r)}function wt(r,i,e){const t=i.map(([n,o])=>n.ast),s=i.map(([n,o])=>o);return St(r,r.z3.mk_pbeq(r.context.ptr,t,s,e))}var dt=(r=>(r[r.HAS_INSTANCE_ID=0]="HAS_INSTANCE_ID",r[r.NOT_HAS_INSTANCE_ID=1]="NOT_HAS_INSTANCE_ID",r[r.HAS_SHAPE_TYPE=2]="HAS_SHAPE_TYPE",r))(dt||{});class D{constructor(i,e){a(this,"ctx");a(this,"_offsetTuples",[]);this.ctx=i;for(const t of e)if(t instanceof d)this._offsetTuples.push([t,void 0]);else if(Array.isArray(t)){const[s,n]=t;this._offsetTuples.push([s,n])}else throw new Error(`Invalid shape offset: ${t}`)}get offsetVectors(){return this._offsetTuples.map(([i])=>i)}get offsetsWithPayloads(){return this._offsetTuples}transform(i){return new D(this.ctx,this._offsetTuples.map(([e,t])=>[i(e),t]))}canonicalize(){const i=this._offsetTuples.slice().sort(([t],[s])=>d.comparator(t,s)),e=i[0][0].negate();return new D(this.ctx,i.map(([t,s])=>[t.translate(e),s]))}equivalent(i){if(this._offsetTuples.length!==i._offsetTuples.length)return!1;for(let e=0;e<this._offsetTuples.length;e++){const[t,s]=this._offsetTuples[e],[n,o]=i._offsetTuples[e];if(!t.equals(n))return!1;if(this.ctx.context.isExpr(s)&&this.ctx.context.isExpr(o)){if(!this.ctx.context.Eq(s,o))return!1}else if(s===void 0){if(o!==void 0)return!1}else if(o===void 0){if(s!==void 0)return!1}else if(s!==o)return!1}return!0}}const S=class S{constructor(i,e,t,s=void 0,n=!1,o=!1,h=!1,c=!1){a(this,"ctx");a(this,"_solver");a(this,"_lattice");a(this,"_complete");a(this,"_allowCopies");a(this,"_shapes");a(this,"_variants",[]);a(this,"_shapeTypeGrid");a(this,"_shapeInstanceGrid");a(this,"_shapePayloadGrid");this.ctx=i,S._instanceIndex+=1,this._solver=s??new this.ctx.context.Solver,this._lattice=e,this._complete=n,this._allowCopies=c,this._shapes=t,this._makeVariants(o,h),this._createGrids(),this._addConstraints()}_makeVariants(i,e){const t=this._lattice.transformationFunctions(i,e);this._variants=[];for(const s of this._shapes){const n=[];for(const o of t){const h=s.transform(o).canonicalize();n.some(c=>c.equivalent(h))||n.push(h)}this._variants.push(n)}}_createGrids(){this._shapeTypeGrid=new Map;for(const e of this._lattice.points){const t=this.ctx.context.Int.const(`scst-${S._instanceIndex}-${e.y}-${e.x}`);this._complete?this._solver.add(t.ge(0)):this._solver.add(t.ge(-1)),this._solver.add(t.lt(this._shapes.length)),this._shapeTypeGrid.set(e,t)}this._shapeInstanceGrid=new Map;for(const e of this._lattice.points){const t=this.ctx.context.Int.const(`scsi-${S._instanceIndex}-${e.y}-${e.x}`);this._complete?this._solver.add(t.ge(0)):this._solver.add(t.ge(-1)),this._solver.add(t.lt(this._lattice.points.length)),this._shapeInstanceGrid.set(e,t)}const i=this._shapes[0].offsetsWithPayloads[0][1];if(i){this._shapePayloadGrid=new Map;let e;if(this.ctx.context.isExpr(i))e=i.sort;else if(typeof i=="number")e=this.ctx.context.Int.sort();else throw new Error(`Could not determine z3 sort for ${i}`);for(const t of this._lattice.points){const s=this.ctx.context.Const(`scsp-${S._instanceIndex}-${t.y}-${t.x}`,e);this._shapePayloadGrid.set(t,s)}}}_addConstraints(){if(this._addGridAgreementConstraints(),this._addShapeInstanceConstraints(),!this._allowCopies)for(let i=0;i<this._shapes.length;i++)this._addSingleCopyConstraints(i,this._shapes[i])}_addGridAgreementConstraints(){for(const[i,e]of this._shapeTypeGrid)this._solver.add(this.ctx.context.Or(this.ctx.context.And(e.eq(-1),this._shapeInstanceGrid.get(i).eq(-1)),this.ctx.context.And(e.neq(-1),this._shapeInstanceGrid.get(i).neq(-1))))}_addShapeInstanceConstraints(){const i={};for(let s=0;s<Math.max(this._lattice.points.length,this._variants.length);s++)i[s]=this.ctx.context.Int.val(s);const e=new M(this.ctx,this._lattice.points);for(const s of this._lattice.points.map(n=>this._lattice.pointToIndex(n)))e.addExpr(`0-${s}`,n=>this.ctx.context.Eq(this._shapeInstanceGrid.get(n),i[s])),e.addExpr(`1-${s}`,n=>this.ctx.context.Not(this.ctx.context.Eq(this._shapeInstanceGrid.get(n),i[s])));for(let s=0;s<this._variants.length;s++)e.addExpr(`2-${s}`,n=>this.ctx.context.Eq(this._shapeTypeGrid.get(n),i[s]));const t=new Q(()=>[]);for(let s=0;s<this._variants.length;s++)for(const n of this._variants[s])for(const o of this._lattice.points){const h=this._lattice.pointToIndex(o),c=[];for(const[l,u]of n.offsetsWithPayloads){const _=o.translate(l);if(!this._shapeInstanceGrid.has(_)){c.length=0;break}c.push([_,u])}if(c.length>0){const l=[];for(const[_,x]of c)l.push(e.getPointExpr(`0-${h}`,_)),l.push(e.getPointExpr(`2-${s}`,_)),this._shapePayloadGrid&&l.push(this._shapePayloadGrid.get(_).eq(x));const u=e.getOtherPointsExpr(`1-${h}`,c.map(([_])=>_));u&&l.push(u),t.get(o).push(this.ctx.context.And(...l))}}for(const s of this._lattice.points){const n=this._lattice.pointToIndex(s),o=e.getOtherPointsExpr(`1-${n}`,[]),h=t.get(s);h.length>0?(h.push(o),this._solver.add(this.ctx.context.Or(...h))):this._solver.add(o)}}_addSingleCopyConstraints(i,e){const t=[];for(const s of this._shapeTypeGrid.values())t.push([s.eq(i),1]);bt(this.ctx,this._solver,wt(this.ctx,t,e.offsetsWithPayloads.length))}get solver(){return this._solver}get shapeTypeGrid(){return this._shapeTypeGrid}getShapeTypeAt(i){return this._shapeTypeGrid.get(i)}get shapeInstanceGrid(){return this._shapeInstanceGrid}getShapeInstanceAt(i){return this._shapeInstanceGrid.get(i)}get shapePayloadGrid(){return this._shapePayloadGrid}getShapePayloadAt(i){return this._shapePayloadGrid.get(i)}shapeTypesToString(){const i=this._solver.model(),e=[...this._shapeTypeGrid.keys()],t=Math.min(...e.map(c=>c.y)),s=Math.min(...e.map(c=>c.x)),n=Math.max(...e.map(c=>c.y)),o=Math.max(...e.map(c=>c.x));let h="";for(let c=t;c<=n;c++){for(let l=s;l<=o;l++){const u=new m(c,l);let _=-1;if(this._shapeTypeGrid.has(u)){const x=this._shapeTypeGrid.get(u);_=Number(i.eval(x))}_>=0?h+=_.toString().padStart(3," "):h+=" "}h+=`
`}return h}shapeInstancesToString(){const i=this._solver.model(),e=[...this._shapeInstanceGrid.keys()],t=Math.min(...e.map(c=>c.y)),s=Math.min(...e.map(c=>c.x)),n=Math.max(...e.map(c=>c.y)),o=Math.max(...e.map(c=>c.x));let h="";for(let c=t;c<=n;c++){for(let l=s;l<=o;l++){const u=new m(c,l);let _=-1;if(this._shapeInstanceGrid.has(u)){const x=this._shapeInstanceGrid.get(u);_=Number(i.eval(x))}_>=0?h+=_.toString().padStart(3," "):h+=" "}h+=`
`}return h}};a(S,"_instanceIndex",0);let A=S;function It(r){return{Shape:function(i){return new D(r,i)},ShapeConstrainer:function(i,e,t=void 0,s=!1,n=!1,o=!1,h=!1){return new A(r,i,e,t,s,n,o,h)}}}const w=0,$=1,f=class f{constructor(i,e,t=void 0,s=!0,n=!1,o=void 0,h=void 0){a(this,"ctx");a(this,"_solver");a(this,"_lattice");a(this,"_complete");a(this,"_minRegionSize");a(this,"_maxRegionSize");a(this,"_edgeSharingDirectionToIndex");a(this,"_parentTypeToIndex");a(this,"_parentTypes");a(this,"_parentGrid");a(this,"_subtreeSizeGrid");a(this,"_regionIdGrid");a(this,"_regionSizeGrid");this.ctx=i,f._instanceIndex+=1,this._lattice=e,this._solver=t??new this.ctx.context.Solver,this._complete=s,o!==void 0?this._minRegionSize=o:this._minRegionSize=1,h!==void 0?this._maxRegionSize=h:this._maxRegionSize=this._lattice.points.length,this._manageEdgeSharingDirections(),this._createGrids(),this._addConstraints(),n&&this._addRectangularConstraints()}_manageEdgeSharingDirections(){this._edgeSharingDirectionToIndex=new P,this._parentTypeToIndex=new Map([["X",w],["R",$]]),this._parentTypes=["X","R"];for(const i of this._lattice.edgeSharingDirections()){const e=this._parentTypes.length;this._parentTypeToIndex.set(i.name,e),this._edgeSharingDirectionToIndex.set(i,e),this._parentTypes.push(i.name)}}_createGrids(){this._parentGrid=new g;for(const i of this._lattice.points){const e=this.ctx.context.Int.const(`rcp-${f._instanceIndex}-${i.y}-${i.x}`);this._complete?this._solver.add(e.ge($)):this._solver.add(e.ge(w)),this._solver.add(e.lt(this._parentTypes.length)),this._parentGrid.set(i,e)}this._subtreeSizeGrid=new g;for(const i of this._lattice.points){const e=this.ctx.context.Int.const(`rcss-${f._instanceIndex}-${i.y}-${i.x}`);this._complete?this._solver.add(e.ge(1)):this._solver.add(e.ge(0)),this._solver.add(e.le(this._maxRegionSize)),this._subtreeSizeGrid.set(i,e)}this._regionIdGrid=new g;for(const i of this._lattice.points){const e=this.ctx.context.Int.const(`rcid-${f._instanceIndex}-${i.y}-${i.x}`);this._complete?this._solver.add(e.ge(0)):this._solver.add(e.ge(-1)),this._solver.add(e.lt(this._lattice.points.length));const t=this._parentGrid.get(i);this._solver.add(t.eq(w).implies(e.eq(-1)));const s=this._lattice.pointToIndex(i);if(s===void 0)throw new Error("Point index is undefined");this._solver.add(t.eq($).implies(e.eq(s))),this._regionIdGrid.set(i,e)}this._regionSizeGrid=new g;for(const i of this._lattice.points){const e=this.ctx.context.Int.const(`rcrs-${f._instanceIndex}-${i.y}-${i.x}`);this._complete?this._solver.add(e.ge(this._minRegionSize)):this._solver.add(e.ge(this._minRegionSize).or(e.eq(-1))),this._solver.add(e.le(this._maxRegionSize));const t=this._parentGrid.get(i),s=this._subtreeSizeGrid.get(i);this._solver.add(t.eq(w).implies(e.eq(-1))),this._solver.add(t.eq($).implies(e.eq(s))),this._regionSizeGrid.set(i,e)}}_addConstraints(){const i=(t,s,n)=>{this._solver.add(this._parentGrid.get(t).eq(w).implies(this._parentGrid.get(s).neq(n))),this._solver.add(this._parentGrid.get(s).eq(n).implies(this.ctx.context.And(this._regionIdGrid.get(t).eq(this._regionIdGrid.get(s)),this._regionSizeGrid.get(t).eq(this._regionSizeGrid.get(s)))))},e=(t,s)=>this.ctx.context.If(this._parentGrid.get(t).eq(s),this._subtreeSizeGrid.get(t),this.ctx.context.Int.val(0));for(const t of this._lattice.points){const s=this._parentGrid.get(t),n=[];for(const o of this._lattice.edgeSharingDirections()){const h=t.translate(o.vector);if(this._parentGrid.has(h)){const c=this._edgeSharingDirectionToIndex.get(this._lattice.oppositeDirection(o));i(t,h,c),n.push(e(h,c))}else{const c=this._edgeSharingDirectionToIndex.get(o);this._solver.add(s.neq(c))}}this._solver.add(this._subtreeSizeGrid.get(t).eq(this.ctx.context.Sum(this.ctx.context.If(s.neq(w),1,0),...n)))}}_addRectangularConstraints(){for(const i of this._lattice.points){const e=this._lattice.edgeSharingNeighbors(this._regionIdGrid,i);for(const[t,s]of N(e,2)){const n=this._lattice.edgeSharingNeighbors(this._regionIdGrid,t.location),o=this._lattice.edgeSharingNeighbors(this._regionIdGrid,s.location),h=new U([...n.map(c=>c.location),...o.map(c=>c.location)]);h.delete(i),h.size>0&&this._solver.add(this.ctx.context.And(t.symbol.eq(this._regionIdGrid.get(i)),s.symbol.eq(this._regionIdGrid.get(i)),this._regionIdGrid.get(i).neq(-1)).implies(this.ctx.context.And(...Array.from(h).map(c=>this._regionIdGrid.get(c).eq(this._regionIdGrid.get(i))))))}}}edgeSharingDirectionToIndex(i){return this._edgeSharingDirectionToIndex.get(i)}parentTypeToIndex(i){return this._parentTypeToIndex.get(i)}get solver(){return this._solver}get regionIdGrid(){return this._regionIdGrid}get regionSizeGrid(){return this._regionSizeGrid}get parentGrid(){return this._parentGrid}get subtreeSizeGrid(){return this._subtreeSizeGrid}treesToString(){const i={X:" ",R:"R",N:"⭡",E:"⭢",S:"⭣",W:"⭠",NE:"⭧",NW:"⭦",SE:"⭨",SW:"⭩"},e=this._solver.model(),t=s=>{const n=this._parentGrid.get(s),o=Number(e.eval(n)),h=this._parentTypes[o];return i[h]};return this._lattice.toString(t," ")}subtreeSizesToString(){const i=this._solver.model(),e=t=>{const s=this._subtreeSizeGrid.get(t);return Number(i.eval(s)).toString().padStart(3," ")};return this._lattice.toString(e," ")}regionIdsToString(){const i=this._solver.model(),e=t=>{const s=this._regionIdGrid.get(t);return Number(i.eval(s)).toString().padStart(3," ")};return this._lattice.toString(e," ")}regionSizesToString(){const i=this._solver.model(),e=t=>{const s=this._regionSizeGrid.get(t);return Number(i.eval(s)).toString().padStart(3," ")};return this._lattice.toString(e," ")}};a(f,"_instanceIndex",0);let F=f;function Gt(r){return{RegionConstrainer:function(i,e=void 0,t=!0,s=!1,n=void 0,o=void 0){return new F(r,i,e,t,s,n,o)}}}const Tt=v(r=>`${r[0].toString()}+${r[1].toString()}`,r=>{const i=r.split("+");return[p.fromString(i[0]),p.fromString(i[1])]});class ht extends q{constructor(e,t=!0){super([]);a(this,"_includeTerminals");a(this,"_symbolsForDirection");a(this,"_symbolForDirectionPair");a(this,"_terminalForDirection");a(this,"_maxPathSegmentSymbolIndex",0);a(this,"_maxPathTerminalSymbolIndex",0);this._includeTerminals=t,this._symbolsForDirection=new H(()=>[]),this._symbolForDirectionPair=new Tt,this._terminalForDirection=new P;const s=e.edgeSharingDirections();[...N(s,2)].forEach(([n,o],h)=>{const c=e.labelForDirectionPair(n,o);this.append(n.name+o.name,c),this._symbolsForDirection.get(n).push(h),this._symbolsForDirection.get(o).push(h),this._symbolForDirectionPair.set([n,o],h),this._symbolForDirectionPair.set([o,n],h),this._maxPathSegmentSymbolIndex=h}),t&&s.forEach(n=>{this.append(n.name,e.labelForDirection(n));const o=this.maxIndex();this._symbolsForDirection.get(n).push(o),this._terminalForDirection.set(n,o),this._maxPathTerminalSymbolIndex=o})}isPath(e){return this._includeTerminals?e.lt(this._maxPathTerminalSymbolIndex+1):e.lt(this._maxPathSegmentSymbolIndex+1)}isPathSegment(e){return e.lt(this._maxPathSegmentSymbolIndex+1)}isTerminal(e){return this._includeTerminals?e.ctx.And(e.gt(this._maxPathSegmentSymbolIndex),e.lt(this._maxPathTerminalSymbolIndex+1)):e.ctx.Bool.val(!1)}symbolsForDirection(e){return this._symbolsForDirection.get(e)}symbolForDirectionPair(e,t){return this._symbolForDirectionPair.get([e,t])}terminalForDirection(e){return this._terminalForDirection.get(e)}}const I=class I{constructor(i,e=!1,t=!0,s=!0){a(this,"_symbolGrid");a(this,"_complete");a(this,"_allowTerminatedPaths");a(this,"_allowLoops");a(this,"_pathInstanceGrid");a(this,"_pathOrderGrid");a(this,"_numPaths");I._instanceIndex+=1,this._symbolGrid=i,this._complete=e,this._allowTerminatedPaths=t,this._allowLoops=s,this._numPaths=null,this._pathInstanceGrid=new g([...this._symbolGrid.grid.keys()].map(n=>[n,this._symbolGrid.ctx.context.Int.const(`pcpi-${I._instanceIndex}-${n.y}-${n.x}`)])),this._pathOrderGrid=new g([...this._symbolGrid.grid.keys()].map(n=>[n,this._symbolGrid.ctx.context.Int.const(`pcpo-${I._instanceIndex}-${n.y}-${n.x}`)])),this._addPathEdgeConstraints(),this._addPathInstanceGridConstraints(),this._addPathOrderGridConstraints(),this._addAllowTerminatedPathsConstraints()}_addPathEdgeConstraints(){const i=this._symbolGrid.solver,e=this._symbolGrid.symbolSet;for(const[t,s]of this._symbolGrid.grid)for(const n of this._symbolGrid.lattice.edgeSharingDirections()){const o=t.translate(n.vector),h=e.symbolsForDirection(n),c=this._symbolGrid.grid.get(o);if(c!==void 0){const l=e.symbolsForDirection(this._symbolGrid.lattice.oppositeDirection(n)),u=i.ctx.Or(...h.map(x=>s.eq(x))),_=i.ctx.Or(...l.map(x=>c.eq(x)));i.add(i.ctx.Implies(u,_))}else for(const l of h)i.add(s.neq(l))}}_addPathInstanceGridConstraints(){const i=this._symbolGrid.solver,e=this._symbolGrid.symbolSet;for(const[t,s]of this._pathInstanceGrid){this._complete?i.add(s.ge(0)):i.add(s.ge(-1)),i.add(s.lt(this._symbolGrid.grid.size));const n=this._symbolGrid.grid.get(t);i.add(e.isPath(n).eq(s.neq(-1)));const o=this._symbolGrid.lattice.pointToIndex(t);if(o===void 0)throw new Error("pointIndex is undefined");i.add(this._pathOrderGrid.get(t).eq(0).eq(s.eq(o)));for(const h of this._symbolGrid.lattice.edgeSharingDirections()){const c=e.symbolsForDirection(h),l=t.translate(h.vector);if(this._symbolGrid.grid.get(l)!==void 0){const _=i.ctx.Or(...c.map(x=>n.eq(x)));i.add(i.ctx.Implies(_,s.eq(this._pathInstanceGrid.get(l))))}}}}*_allDirectionPairs(){const i=this._symbolGrid.lattice.edgeSharingDirections();let e=0;for(const[t,s]of N(i,2))yield[e,t,s],e+=1}_addPathOrderGridConstraints(){const i=this._symbolGrid.solver,e=this._symbolGrid.symbolSet;for(const[t,s]of this._pathOrderGrid){this._complete?i.add(s.ge(0)):i.add(s.ge(-1));const n=this._symbolGrid.grid.get(t);i.add(e.isPath(n).eq(s.neq(-1)));for(const o of this._symbolGrid.lattice.edgeSharingDirections()){const h=e.terminalForDirection(o);if(h===void 0)continue;const c=t.translate(o.vector);this._pathOrderGrid.has(c)&&i.add(i.ctx.Implies(n.eq(h),i.ctx.Or(i.ctx.And(s.eq(0),this._pathOrderGrid.get(c).eq(1)),i.ctx.And(s.gt(0),this._pathOrderGrid.get(c).eq(s.sub(1))))))}for(const[o,h,c]of this._allDirectionPairs()){const l=t.translate(h.vector),u=t.translate(c.vector);this._pathOrderGrid.has(l)&&this._pathOrderGrid.has(u)&&(i.add(i.ctx.Implies(n.eq(o),this._pathOrderGrid.get(l).neq(this._pathOrderGrid.get(u)))),i.add(i.ctx.Implies(i.ctx.And(n.eq(o),s.gt(0)),i.ctx.Or(i.ctx.And(this._pathOrderGrid.get(l).eq(s.sub(1)),i.ctx.Or(this._pathOrderGrid.get(u).eq(s.add(1)),this._allowLoops?this._pathOrderGrid.get(u).eq(0):i.ctx.Bool.val(!1))),i.ctx.And(i.ctx.Or(this._pathOrderGrid.get(l).eq(s.add(1)),this._allowLoops?this._pathOrderGrid.get(l).eq(0):i.ctx.Bool.val(!1)),this._pathOrderGrid.get(u).eq(s.sub(1)))))))}}}_addAllowTerminatedPathsConstraints(){const i=this._symbolGrid.solver,e=this._symbolGrid.symbolSet;if(!this._allowTerminatedPaths)for(const t of this._symbolGrid.grid.values())this._symbolGrid.solver.add(i.ctx.Not(e.isTerminal(t)))}get numPaths(){if(this._numPaths===null){const i=this._symbolGrid.solver,e=this._symbolGrid.lattice.points.map(t=>i.ctx.If(this._pathOrderGrid.get(t).eq(0),1,0));this._numPaths=this._symbolGrid.ctx.context.Sum(e[0],...e.slice(1))}return this._numPaths}get pathInstanceGrid(){return this._pathInstanceGrid}get pathOrderGrid(){return this._pathOrderGrid}pathNumberingToString(){const i=this._symbolGrid.solver.model(),e=t=>{const s=Number(i.eval(this._pathInstanceGrid.get(t))),n=Number(i.eval(this._pathOrderGrid.get(t)));return s===-1?" ":`${String.fromCharCode(65+s)}${n.toString().padStart(2,"0")} `};return this._symbolGrid.lattice.toString(e," ")}};a(I,"_instanceIndex",0);let W=I;const Et=Object.freeze(Object.defineProperty({__proto__:null,PathConstrainer:W,PathSymbolSet:ht},Symbol.toStringTag,{value:"Module"}));function Dt(r){return{...xt,...gt(r),...mt(r),...ft,...yt(r),...It(r),...Gt(r),...Et}}exports.DefaultDirectionMap=H;exports.DefaultPointMap=Q;exports.DefaultVectorMap=et;exports.Direction=p;exports.DirectionMap=P;exports.DirectionSet=it;exports.ExpressionQuadTree=M;exports.FlatToppedHexagonalLattice=O;exports.HexagonalLattice=G;exports.Lattice=b;exports.Neighbor=Z;exports.PathConstrainer=W;exports.PathSymbolSet=ht;exports.Point=m;exports.PointMap=g;exports.PointSet=U;exports.PointyToppedHexagonalLattice=C;exports.RectangularLattice=E;exports.RegionConstrainer=F;exports.Shape=D;exports.ShapeConstrainer=A;exports.ShapeExprKey=dt;exports.Symbol=T;exports.SymbolGrid=z;exports.SymbolSet=q;exports.Vector=d;exports.VectorMap=Y;exports.VectorSet=tt;exports.combinations=N;exports.countCells=ot;exports.createDefualtMap=k;exports.createStringMap=v;exports.createStringSet=L;exports.getRectangleLattice=J;exports.getSquareLattice=st;exports.grilops=Dt;exports.makeLetterRangeSymbolSet=nt;exports.makeNumberRangeSymbolSet=rt;exports.reduceCells=K;exports.zip=B;