/******************************************************************************
* 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.simple;
import static com.ibm.wala.memsat.util.Programs.executionOrder;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.ibm.wala.memsat.concurrent.Execution;
import com.ibm.wala.memsat.concurrent.Justification;
import com.ibm.wala.memsat.concurrent.MemoryModel;
import com.ibm.wala.memsat.concurrent.Program;
import com.ibm.wala.memsat.concurrent.Program.BoundsBuilder;
import com.ibm.wala.memsat.frontEnd.InlinedInstruction;
import com.ibm.wala.memsat.util.Programs;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.util.graph.Graph;
import kodkod.ast.Expression;
import kodkod.ast.Formula;
import kodkod.ast.Relation;
import kodkod.instance.Bounds;
/**
* A base implementation of the {@linkplain MemoryModel} interface,
* suitable for the specification of simple (non-hybrid) memory models
* defined by Yang et al [1].
*
* @see [1] Y.�Yang, G.�Gopalakrishnan, G.�Lindstrom, and K.�Slind.
* Nemos: a framework for axiomatic and executable specifications of memory consistency models.
* In IPDPS �04, pages 26�30, 2004.
*
* @specfield memInstructions: set MethodReference
*
* @author etorlak
*/
abstract class SimpleMemoryModel<T> implements MemoryModel {
private final Set<MethodReference> memInsts;
/**
* Constructs an AbstractMemoryModel with no special memory instructions.
* @effects this.memInstructions' = memInsts
*/
protected SimpleMemoryModel() { memInsts = Collections.emptySet(); }
/**
* {@inheritDoc}
* @see com.ibm.wala.memsat.concurrent.MemoryModel#memoryInstructions()
*/
public final Set<MethodReference> memoryInstructions() { return memInsts; }
/**
* Returns false.
* @return false
*/
public final boolean usesSpeculation() { return false; }
/**
* Returns the main execution that will be used in the justification of the given program.
* @return main execution that will be used in the justification of the given program.
*/
protected abstract SimpleExecution<T> execution(Program prog);
/**
* Returns the consistency constraints for the given execution of the given program.
* @requires exec.prog = prog
* @return consistency constraints for the given execution of the given program.
*/
protected abstract Formula consistencyConstraints(Program prog, SimpleExecution<T> exec);
/**
* Returns the bounds for the relations used in the specification of the given program
* and execution. The default implementation returns a bounds built by applying a
* {@linkplain Program#builder() prog.builder} to exec and to each ordering in exec.
* The upper bound on the orderings is given by {@linkplain Programs#executionOrder(com.ibm.wala.memsat.frontEnd.WalaInformation)
* executionOrder(prog.info)}.
* @requires exec.prog = prog
* @return bounds for the given execution of the given program.
*/
protected Bounds bounds(Program prog, SimpleExecution<T> exec) {
final BoundsBuilder builder = prog.builder();
builder.boundExecution(exec);
final Graph<InlinedInstruction> execOrd = executionOrder(prog.info());
for(Relation ord : exec.orderings()) {
builder.boundOrdering(ord, execOrd);
}
return builder.build();
}
/**
* {@inheritDoc}
* @see com.ibm.wala.memsat.concurrent.MemoryModel#justify(com.ibm.wala.memsat.concurrent.Program)
*/
public final Justification justify(final Program prog) {
final SimpleExecution<T> exec = execution(prog);
final Formula formula = prog.sequentiallyValid(exec).and(consistencyConstraints(prog, exec));
final Bounds bounds = bounds(prog, exec);
return new Justification() {
public Execution execution() { return exec; }
public Formula formula() { return formula; }
public Bounds bounds() { return bounds; }
public Program program() { return prog; }
public List<? extends Execution> speculations() { return Collections.emptyList(); }
public List<? extends Expression> commits() { return Collections.emptyList(); }
};
}
/**
* {@inheritDoc}
* @see java.lang.Object#toString()
*/
public String toString() { return getClass().getSimpleName(); }
}