001package org.clafer.ast.analysis; 002 003import java.util.HashMap; 004import java.util.Map; 005import org.clafer.ast.AstAbstractClafer; 006import org.clafer.ast.AstConcreteClafer; 007import org.clafer.ast.Card; 008 009/** 010 * Rewrites the model replacing unbounded high cardinalities with bounded 011 * effective high cardinalities. 012 * 013 * @author jimmy 014 */ 015public class CardAnalyzer implements Analyzer { 016 017 @Override 018 public Analysis analyze(Analysis analysis) { 019 Map<AstConcreteClafer, Card> cardMap = new HashMap<>(); 020 cardMap.put(analysis.getModel(), new Card(1, 1)); 021 for (AstAbstractClafer abstractClafer : analysis.getAbstractClafers()) { 022 analyze(abstractClafer, cardMap, analysis); 023 } 024 for (AstConcreteClafer child : analysis.getModel().getChildren()) { 025 analyze(child, 1, cardMap, analysis); 026 } 027 return analysis.setCardMap(cardMap); 028 } 029 030 private static void analyze(AstAbstractClafer clafer, Map<AstConcreteClafer, Card> cardMap, Analysis analysis) { 031 Card globalCard = analysis.getGlobalCard(clafer); 032 for (AstConcreteClafer child : clafer.getChildren()) { 033 analyze(child, globalCard.getLow(), cardMap, analysis); 034 } 035 } 036 037 private static void analyze(AstConcreteClafer clafer, int parentlowGlobalCard, Map<AstConcreteClafer, Card> cardMap, Analysis analysis) { 038 int low = analysis.getCard(clafer).getLow(); 039 int high = analysis.getCard(clafer).getHigh(); 040 Card globalCard = analysis.getGlobalCard(clafer); 041 042 int evenlyDistributed = parentlowGlobalCard * low; 043 int rest = globalCard.getHigh() - evenlyDistributed; 044 cardMap.put(clafer, new Card(low, Math.min(high, low + rest))); 045 046 for (AstConcreteClafer child : clafer.getChildren()) { 047 analyze(child, globalCard.getLow(), cardMap, analysis); 048 } 049 } 050}