001package org.clafer.compiler; 002 003import java.util.ArrayList; 004import java.util.List; 005import org.clafer.ast.AstAbstractClafer; 006import org.clafer.ast.AstClafer; 007import org.clafer.ast.AstConcreteClafer; 008import org.clafer.ast.compiler.AstSolutionMap; 009import org.clafer.collection.Pair; 010import org.clafer.common.Check; 011import org.clafer.instance.InstanceClafer; 012import org.clafer.instance.InstanceModel; 013import org.clafer.instance.InstanceRef; 014import org.clafer.ir.IrIntVar; 015import org.clafer.ir.IrSetVar; 016import org.clafer.ir.compiler.IrSolutionMap; 017 018/** 019 * 020 * @author jimmy 021 */ 022public class ClaferSolutionMap { 023 024 private final AstSolutionMap astSolution; 025 private final IrSolutionMap irSolution; 026 027 ClaferSolutionMap(AstSolutionMap astSolution, IrSolutionMap irSolution) { 028 this.astSolution = Check.notNull(astSolution); 029 this.irSolution = Check.notNull(irSolution); 030 } 031 032 public InstanceModel getInstance() { 033 List<InstanceClafer> topInstances = new ArrayList<>(); 034 for (AstConcreteClafer child : astSolution.getModel().getChildren()) { 035 // [0] because top clafers only have exactly one children set 036 IrSetVar topSetIrVar = astSolution.getSiblingVars(child)[0]; 037 int[] topIds = irSolution.getSetValue(topSetIrVar); 038 for (int topId : topIds) { 039 topInstances.add(getInstanceClafer(child, topId)); 040 } 041 } 042 return new InstanceModel(topInstances.toArray(new InstanceClafer[topInstances.size()])); 043 } 044 045 private InstanceClafer getInstanceClafer(AstConcreteClafer clafer, int id) { 046 List<InstanceClafer> children = new ArrayList<>(); 047 InstanceRef ref = getInstanceClafer(clafer, id, children); 048 return new InstanceClafer(clafer, id, ref, children.toArray(new InstanceClafer[children.size()])); 049 } 050 051 private InstanceRef getInstanceClafer(AstClafer clafer, int id, List<InstanceClafer> children) { 052 for (AstConcreteClafer child : clafer.getChildren()) { 053 IrSetVar childSetIrVar = astSolution.getSiblingVars(child)[id]; 054 int[] childIds = irSolution.getSetValue(childSetIrVar); 055 for (int childId : childIds) { 056 children.add(getInstanceClafer(child, childId)); 057 } 058 } 059 InstanceRef ref = null; 060 if (clafer.hasSuperClafer()) { 061 ref = getInstanceClafer(clafer.getSuperClafer(), 062 id + astSolution.getAnalysis().getOffsets(clafer.getSuperClafer()).getOffset(clafer), 063 children); 064 } 065 if (clafer.hasRef()) { 066 IrIntVar refIrVar = astSolution.getRefVars(clafer.getRef())[id]; 067 AstClafer targetType = clafer.getRef().getTargetType(); 068 int value = irSolution.getIntValue(refIrVar); 069 if (targetType instanceof AstAbstractClafer) { 070 Pair<AstConcreteClafer, Integer> concreteRef = astSolution.getAnalysis().getConcreteId( 071 targetType, value); 072 targetType = concreteRef.getFst(); 073 value = concreteRef.getSnd().intValue(); 074 } 075 ref = new InstanceRef(targetType, value); 076 } 077 return ref; 078 } 079 080 public AstSolutionMap getAstSolution() { 081 return astSolution; 082 } 083 084 public IrSolutionMap getIrSolution() { 085 return irSolution; 086 } 087}