/* * Mapping.java * ------------- * * Records a mapping from a set of arguments to another set of arguments. * For the * * $Id: Mapping.java,v 1.14 2000/11/17 01:35:38 chenli Exp $ */ import java.util.*; class Mapping { Map map = null; // recording the map Mapping() { map = new HashMap(); } Mapping(Map map) { this.map = map; } public Map getMap() { return map; } /** * Clones this mapping. */ public Object clone() { HashMap newMap = new HashMap(); Set entrySet = (Set) map.entrySet(); for (Iterator iter = entrySet.iterator(); iter.hasNext();) { Map.Entry mapEntry = (Map.Entry) iter.next(); Argument srcArg = (Argument) mapEntry.getKey(); Argument dstArg = (Argument) mapEntry.getValue(); newMap.put(srcArg, dstArg); } return new Mapping(newMap); } /** * Returns a vector of the source args. */ public Vector getSrcArgs() { Vector srcArgs = new Vector(); Set entrySet = (Set) map.entrySet(); for (Iterator iter = entrySet.iterator(); iter.hasNext();) { Map.Entry mapEntry = (Map.Entry) iter.next(); Argument srcArg = (Argument) mapEntry.getKey(); srcArgs.add(srcArg); } return srcArgs; } /** * Returns a vector of the dst args. */ public Vector getDstArgs() { Vector dstArgs = new Vector(); Set entrySet = (Set) map.entrySet(); for (Iterator iter = entrySet.iterator(); iter.hasNext();) { Map.Entry mapEntry = (Map.Entry) iter.next(); Argument dstArg = (Argument) mapEntry.getValue(); dstArgs.add(dstArg); } return dstArgs; } /** * Inserts a new pair of argument */ public void put(Argument srcArg, Argument dstArg) { if (map.get(srcArg) != null) UserLib.myerror("Mapping.put(), srcArg already exists."); map.put(srcArg, dstArg); } /** * Extends this mapping: for the variables in args that are not * mapped in the map, we map them to themselves. Note that args should * be a superset of srcArgs and dstArgs * * This operation will set srcArgs and dstArgs to args */ /*void extendToIndentity(Vector args) { Vector srcArgs = getSrcArgs(); // check if args is a superset of srcArgs for (int i = 0; i < srcArgs.size(); i ++) { // if this arg is not mapped, map it to itself Argument arg = (Argument) srcArgs.elementAt(i); // !!!if (arg.isConst()) continue; // we don't check constants if (!args.contains(arg)) UserLib.myerror("Mapping.extendToIndentity(): " + "args should be a superset of srcArgs."); } for (int i = 0; i < args.size(); i ++) { // if this arg is not mapped, maps it to itself if (!map.containsKey(args.elementAt(i))) map.put(args.elementAt(i), args.elementAt(i)); } }*/ /** * Applies the mapping on an argument to get a new argument. if the argument is mapped, use the identity mapping. */ public Argument applyTryIdentity(Argument srcArg) { Argument dst = this.apply(srcArg); if (dst != null) return dst; return srcArg; // identity } /** * Applies the mapping on an argument to get a new argument */ public Argument apply(Argument srcArg) { Argument dst = (Argument) map.get(srcArg); return dst; } /** * Applies the mapping on a subgoal to get a new subgoal */ public Subgoal apply(Subgoal srcSubgoal) { // the only difference is the list of arguments Vector args = srcSubgoal.getArgs(); // applies on each argument Vector newArgs = new Vector(); for (int i = 0; i < args.size(); i ++) { Argument srcArg = (Argument) args.elementAt(i); Argument dstArg = this.applyTryIdentity(srcArg); newArgs.add(dstArg); } return new Subgoal(srcSubgoal.getName(), newArgs); } /** * Applies the mapping on a query and gets a new query */ public Query apply(Query srcQuery) { // the only difference is the head and the body Vector body = srcQuery.getBody(); // applies the head on the head Subgoal newHead = this.apply(srcQuery.getHead()); /* TODO for (int i = 0; i < head.size(); i ++) { Argument srcArg = (Argument) head.elementAt(i); Argument dstArg = this.apply(srcArg); if (dstArg == null) UserLib.myerror("Mapping.apply(query): dstArg should not be null."); newHead.add(dstArg); // a new argument }*/ // applies the hh on the body Vector newBody = new Vector(); for (int i = 0; i < body.size(); i ++) { Subgoal srcSubgoal = (Subgoal) body.elementAt(i); Subgoal dstSubgoal = this.apply(srcSubgoal); if (dstSubgoal == null) UserLib.myerror("Mapping.apply(query): " + " dstSubgoal should not be null.\n" + "srcSubgoal is: " + srcSubgoal.toString()); newBody.add(dstSubgoal); } return (new Query(srcQuery.getName(), newHead, newBody)); } /** * returns a new mapping accoroding to a renaming */ public Mapping rename(Map renameMap) { // changes the mapping Map newMap = new HashMap(); Set entrySet = (Set) map.entrySet(); for (Iterator iter = entrySet.iterator(); iter.hasNext();) { Map.Entry mapEntry = (Map.Entry) iter.next(); Argument srcArg = (Argument) mapEntry.getKey(); Argument dstArg = (Argument) mapEntry.getValue(); // new args Argument newSrcArg = (Argument) map.get(srcArg); Argument newDstArg = (Argument) map.get(dstArg); if (newSrcArg == null || newDstArg == null) UserLib.myerror("Mapping.rename(), we should find the targets."); // add this pair newMap.put(newSrcArg, newDstArg); } return new Mapping(newMap); } /** * Given an argument, finds the tail argument on the list starting from * the head argument. */ public Argument getTail(Argument headArg) { Argument tailArg = headArg; while (map.get(tailArg) != null) tailArg = (Argument) map.get(tailArg); return tailArg; } /** * Returns a string. */ public String toString() { StringBuffer result = new StringBuffer(); Set entrySet = (Set) map.entrySet(); for (Iterator iter = entrySet.iterator(); iter.hasNext();) { Map.Entry mapEntry = (Map.Entry) iter.next(); Argument srcArg = (Argument) mapEntry.getKey(); Argument dstArg = (Argument) mapEntry.getValue(); result.append(srcArg.toString() + "->" + dstArg.toString()); if (iter.hasNext()) result.append(", "); } return result.toString(); } }