UNPKG

@logic-pad/core

Version:
65 lines (64 loc) 2.91 kB
import Z3Module from './z3Module.js'; import { instance as myopiaInstance, } from '../../../symbols/myopiaSymbol.js'; import { Point, reduceCells } from 'grilops'; import { DIRECTIONS, ORIENTATIONS } from '../../../primitives.js'; import { convertDirection } from '../utils.js'; import { move } from '../../../dataHelper.js'; export default class MyopiaModule extends Z3Module { constructor() { super(...arguments); Object.defineProperty(this, "id", { enumerable: true, configurable: true, writable: true, value: myopiaInstance.id }); } encode(grid, ctx) { const symbols = grid.symbols.get(this.id); // optimizations if (!symbols || symbols.length === 0) { return; } // encode for real for (const symbol of symbols) { const x = Math.floor(symbol.x); const y = Math.floor(symbol.y); const startPos = new Point(y, x); const origin = ctx.grid.cellAt(new Point(y, x)); const pointedTerms = []; const otherTerms = []; ORIENTATIONS.filter(d => symbol.directions[d]).forEach(direction => { pointedTerms.push(reduceCells(ctx.grid.ctx, ctx.grid, startPos, convertDirection(direction), ctx.ctx.Int.val(0), (acc, cell, p) => { const nextPos = move({ x: p.x, y: p.y }, direction); if (grid.isPositionValid(nextPos.x, nextPos.y)) { return ctx.ctx.If(cell.eq(origin), acc.add(1), acc); } else { return ctx.ctx.If(cell.eq(origin), acc.add(Number.MAX_SAFE_INTEGER), acc); } }, (_, cell) => cell.neq(origin))); }); (symbol.diagonals ? ORIENTATIONS : DIRECTIONS) .filter(d => !symbol.directions[d]) .forEach(direction => { otherTerms.push(reduceCells(ctx.grid.ctx, ctx.grid, startPos, convertDirection(direction), ctx.ctx.Int.val(0), (acc, cell, p) => { const nextPos = move({ x: p.x, y: p.y }, direction); if (grid.isPositionValid(nextPos.x, nextPos.y)) { return ctx.ctx.If(cell.eq(origin), acc.add(1), acc); } else { return ctx.ctx.If(cell.eq(origin), acc.add(Number.MAX_SAFE_INTEGER), acc); } }, (_, cell) => cell.neq(origin))); }); for (let i = 1; i < pointedTerms.length; i++) { ctx.solver.add(pointedTerms[i].eq(pointedTerms[0])); } for (const otherTerm of otherTerms) { ctx.solver.add(otherTerm.gt(pointedTerms[0])); } } } } export const instance = new MyopiaModule();