001package org.clafer.ast.analysis; 002 003import gnu.trove.list.array.TIntArrayList; 004import org.clafer.common.Util; 005 006/** 007 * 008 * @author jimmy 009 */ 010public class PartialSolution { 011 012 // solution[i] = true <=> i exists 013 // solution[i] = false <=> i unknown 014 private final boolean[] solution; 015 // parent[i] = the list of possible parents 016 private final int[][] parent; 017 // siblings[i] = the list of possible siblings 018 private final int[][] siblings; 019 020 public PartialSolution(boolean[] solution, int[][] parent) { 021 this.solution = solution; 022 this.parent = parent; 023 this.siblings = new int[parent.length][]; 024 TIntArrayList array = new TIntArrayList(parent.length); 025 for (int i = 0; i < siblings.length; i++) { 026 array.clear(); 027 for (int j = 1; j < siblings.length; j++) { 028 if (i != j) { 029 // TODO: shouldn't be null. 030 if (parent[i] != null && parent[j] != null) { 031 if (overlaps(parent[i], parent[j])) { 032 array.add(j); 033 } 034 } 035 } 036 } 037 siblings[i] = array.toArray(); 038 } 039 } 040 041 private static boolean overlaps(int[] a, int[] b) { 042 for (int i : a) { 043 if (Util.in(i, b)) { 044 return true; 045 } 046 } 047 return false; 048 } 049 050 /** 051 * @param id 052 * @return true if id exists, false if unknown. 053 */ 054 public boolean hasClafer(int id) { 055 return solution[id]; 056 } 057 058 public boolean[] getSolution() { 059 return solution; 060 } 061 062 public int[] getKnownClafers() { 063 return Util.trues(solution); 064 } 065 066 public int[] getUnknownClafers() { 067 return Util.falses(solution); 068 } 069 070 /** 071 * @param id 072 * @return possible parents of {@code id} 073 */ 074 public int[] getPossibleParents(int id) { 075 return parent[id]; 076 } 077 078 /** 079 * @return {@code true} if and only if all parents are known, {@code false} 080 * otherwise 081 */ 082 public boolean parentSolutionKnown() { 083 for (int[] p : parent) { 084 if (p.length != 1) { 085 return false; 086 } 087 } 088 return true; 089 } 090 091 /** 092 * @param id 093 * @return possible siblings of {@code id} 094 */ 095 public int[] getPossiblesSiblings(int id) { 096 return siblings[id]; 097 } 098 099 public int size() { 100 return solution.length; 101 } 102}