logic-solver-plus
Version:
A fork of logic-solver that is compiled to wasm instead of JS with additional features
126 lines (124 loc) • 4.82 kB
JavaScript
import Logic from './index.mjs'
Logic.superCompile=async function(formula){
let solver = new Logic.Solver()
await solver.initialize()
let trueGenerated = solver._termifier.generate(true,formula)
let falseGenerated = solver._termifier.generate(false,formula)
let trueSolver = solver.solveAssuming(formula)
let falseSolver = solver.solveAssuming(Logic.not(formula))
if(formula.bits1&&formula.bits2){
let bits1 = formula.bits1.bits
let bits2 = formula.bits2.bits
let totalCount = Math.max(getCount(falseGenerated),getCount(trueGenerated))
let curr = bits1.concat(bits2)
let result = iterateOverPermutations(curr,solver,[falseSolver,trueSolver],formula,totalCount)
console.log("curr",curr)
return result
}
}
let getCount = x=>x.map(e=>e.terms.length).reduce((a,b)=>a+b,0)
let solver = new Logic.Solver()
await solver.initialize()
let noop = ()=>{}
let count = 0
let processCurrentIteration = (...args)=>{
let [curr,solver,solvers,formula] = args
if(count++%10000==0||1)console.log(count,curr)
let combined = Logic.and(...curr)
let otherSolutions = [0,1].map(e=>solver.solveAssuming(e?combined:Logic.not(combined)))
return [[0,0],[0,1],[1,0],[1,1]].every(([a,b])=>{
let solution1 = solvers[a]
let solution2 = otherSolutions[b]
return solution2&&solution1.evaluate(Logic.equiv(formula,combined))&&solution2.evaluate(Logic.equiv(formula,combined))
})&&[combined,curr,"----",solver._getFormulaInfo(combined),"---",solver._termifier.generate(false,combined),"--",solver._termifier.generate(true,combined),"-",solver._termifier.generate(true,formula)]
}
let getCombined0 = ()=>{
let doneCombinations = {}
return (bit1,bit2)=>{
let curr = JSON.stringify([bit1,bit2])
if(doneCombinations[curr]){
return
}
doneCombinations[curr] = true
return Logic.or(bit1,bit2)
}
}
let iterateOverPermutations = (bits,solver,solutions,formula,totalCount=1/0,remaining=[],prevent=[])=>{
let getCombined = getCombined0()
if(remaining.length===totalCount){
return
}
let amount = bits.length
let deleteCheckMulti = 3**amount*5**amount
for(let i = 0; i<amount; i++){
let currI = bits[i]
for(let j = 0; j<amount; j++){
if(j===i)continue
let currJ = bits[j]
let hash = 2**i*3**j
if(prevent[hash]){
continue
}
let currBits = bits.slice()
if(hash%deleteCheckMulti===0){
currBits.splice(j,1)
currBits.splice(i,1)
}
let currPrevent = prevent.slice()
currPrevent[hash] = true
let curr = getCombined(currI,currJ)
let currRemaining = remaining.slice()
if(curr)currRemaining.push(curr)
let result = processCurrentIteration(currRemaining,solver,solutions,formula)
if(result){
return result
}
iterateOverPermutations(currBits,solver,solutions,formula,totalCount,currRemaining,currPrevent)
}
}
let deleteCheck = 11
for(let i = 0; i<amount; i++){
let currBits = bits.slice()
let curr = bits[i]
let hash = 7**i
let currPrevent = prevent.slice()
if(currPrevent[hash]||hash%deleteCheck===0){
continue
}
currPrevent[hash] = true
let currRemaining = remaining.slice()
currRemaining.push(curr)
let result = processCurrentIteration(currRemaining,solver,solutions,formula)
if(result){
return result
}
iterateOverPermutations(currBits,solver,solutions,formula,totalCount,currRemaining,currPrevent)
hash*=11
curr = Logic.not(bits[i])
currPrevent = prevent.slice()
currPrevent[hash] = true
currBits = bits.slice()
currBits.splice(i,1)
currRemaining = remaining.slice()
currRemaining.push(curr)
result = processCurrentIteration(currRemaining,solver,solutions,formula)
if(result){
return result
}
iterateOverPermutations(currBits,solver,solutions,formula,totalCount,currRemaining,currPrevent)
}
}
let a = Logic.variableBits("a",2)
let c2 = Logic.constantBits(2)
let cond = Logic.greaterThan(a,c2)
let found = await Logic.superCompile(cond)
//console.log(cond)
console.log(Object.fromEntries(Object.entries(cond).map(function r([k,v]){
if(!Array.isArray(v)){
return [k,Object.fromEntries(Object.entries(v).map(r))]
}
return [k,v.map(e=>solver.toNumTerm(e))]
})))
console.log(solver._termifier.generate(false,cond))
console.log(solver)
console.log("a",JSON.stringify(found,null,2))