/****************************************************************************** * Copyright (c) 2009 - 2015 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *****************************************************************************/ /** * */ package com.ibm.wala.memsat.concurrent.memory; import static com.ibm.wala.memsat.util.Programs.instructions; import static com.ibm.wala.memsat.util.Strings.instructionNames; import java.util.LinkedHashMap; import java.util.Map; import com.ibm.wala.memsat.concurrent.Execution; import com.ibm.wala.memsat.concurrent.Program; import com.ibm.wala.memsat.frontEnd.InlinedInstruction; import kodkod.ast.Expression; import kodkod.ast.Relation; /** * A base implementation of the {@linkplain Execution} interface * that implements convenience methods for computing * various subsets of executed actions. * * @specfield prog: Program * @specfield mem: MemoryModel * @specfield action: prog.instructions ->one Expression * @specfield v, w, location, monitor: Expression * * @author etorlak */ public abstract class AbstractExecution implements Execution { private final Map<InlinedInstruction, Relation> insts; private final Relation v, w, location, monitor; /** * Constructs a new abstract execution for the given program. * The constructor creates and caches a fresh relation for each * {@linkplain InlinedInstruction} in the given program. The * relation names are derived from the instruction names and the * given suffix. This constructor also allocates fresh Relations * for the V, W, location and monitor relations. These are named * by appending the given suffix to "V," "W," "location," and "monitor," * respectively. * @effects this.action' in prog.instructions lone->one Relation */ protected AbstractExecution(Program prog, String suffix) { this.insts = new LinkedHashMap<InlinedInstruction, Relation>(); for(Map.Entry<InlinedInstruction,String> named : instructionNames(instructions(prog.info())).entrySet()) { insts.put(named.getKey(), Relation.unary(named.getValue()+suffix)); } this.v = Relation.binary("V"+suffix); this.w = Relation.binary("W"+suffix); this.location = Relation.binary("location"+suffix); this.monitor = Relation.binary("monitor"+suffix); } /** * {@inheritDoc} * @see com.ibm.wala.memsat.concurrent.Execution#action(com.ibm.wala.memsat.frontEnd.InlinedInstruction) */ public final Relation action(InlinedInstruction inst) { return insts.get(inst); } /** * Returns a unary expression that evaluates to all actions executed by this Execution. * @return Expression.union(this.action[InlinedInstruction]) */ public final Expression actions() { return Expression.union(insts.values()); } /** * {@inheritDoc} * @see com.ibm.wala.memsat.concurrent.Execution#v() */ public final Relation v() { return v; } /** * {@inheritDoc} * @see com.ibm.wala.memsat.concurrent.Execution#w() */ public final Relation w() { return w; } /** * {@inheritDoc} * @see com.ibm.wala.memsat.concurrent.Execution#location() */ public final Relation location() { return location; } /** * {@inheritDoc} * @see com.ibm.wala.memsat.concurrent.Execution#monitor() */ public final Relation monitor() { return monitor; } /** * Returns the write last seen by the given read (if r evaluates to a read in this.actions). * @requires r.arity = 1 * @return r.(this.w) */ public final Expression w(Expression r) { return r.join(w); } /** * Returns the value written by the given write (which may be the empty set). * @requires w.arity = 1 * @return w.(this.v) */ public final Expression v(Expression w) { return w.join(v); } /** * Returns an expression that evaluates to the location on which the given action is performed * or to the empty set if the given expression does not evaluate to a read/write action in this.actions. * The expression representing the location of an action is not necessarily a singleton. * @requires a.arity = 1 * @return a.(this.location) */ public final Expression locationOf(Expression a) { return a.join(location); } /** * Returns an expression that evaluates to the monitor on which the given action is performed or to * the empty set if the given expression does not evaluate to a lock/unlock in this.actions. * @requires action.arity = 1 * @return a.(this.monitor) */ public final Expression monitorOf(Expression a) { return a.join(monitor); } /** * Returns the lock/unlock actions performed on the given monitor or to * the empty set if the given expression does not evaluate to a monitor accessed during this Execution. * @requires m.arity = 1 * @return (this.monitor).m */ public final Expression syncsOn(Expression m) { return monitor.join(m); } /** * {@inheritDoc} * @see java.lang.Object#toString() */ public String toString() { return getClass().getSimpleName(); } }