Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Veymont gen par #1053

Merged
merged 22 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d2c023d
trying to add methods to thread classes
petravandenbos-utwente Mar 31, 2023
63b5ed6
partial code for adding channel fields
petravandenbos-utwente Apr 3, 2023
5353014
importing Channel class
petravandenbos-utwente Apr 4, 2023
1499e93
rewriting channel classes gives NoSuchElementException
petravandenbos-utwente May 31, 2023
7f20f3f
NoSuchElementException resolved
petravandenbos-utwente May 31, 2023
c67dc4c
running without errors but no thread classes printed
petravandenbos-utwente Jun 1, 2023
05f14d6
edit
petravandenbos-utwente Jun 6, 2023
98b6654
merged with dev
petravandenbos-utwente Jun 6, 2023
563d310
busy fixing refs but not working yet
petravandenbos-utwente Jun 6, 2023
b3e4cfb
rewritting method call not working because overloaded dispatch for Ref
petravandenbos-utwente Jun 7, 2023
f362bdc
rewriting method call works
petravandenbos-utwente Jun 12, 2023
a30bf5d
working on rewriting VeyMont Comm Expr
petravandenbos-utwente Jun 13, 2023
f4961fc
rewriting of statements working but channel class type is not rewritten
petravandenbos-utwente Jun 16, 2023
6c93b76
rewriting MessageType now compiling
petravandenbos-utwente Jun 27, 2023
8cb1d51
method invokation refs fixed
petravandenbos-utwente Jul 4, 2023
c102654
stuck at NoSuchElementException
petravandenbos-utwente Jul 12, 2023
f36c2ba
VeyMont produces output
petravandenbos-utwente Jul 13, 2023
5866439
A reference to the successor of this declaration was made, but it has…
petravandenbos-utwente Jul 17, 2023
308204b
rewriting constructor to original format
petravandenbos-utwente Jul 17, 2023
0a16fa6
compiling Java code
petravandenbos-utwente Jul 18, 2023
048dc61
merged with dev
petravandenbos-utwente Jul 18, 2023
07bd995
layout fixes
petravandenbos-utwente Jul 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples/technical/veymont-seq-progs/veymont-swap.pvl
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ seq_program SeqProgram(int x, int y) {
thread s1 = Storage(x);
thread s2 = Storage(y);

int num() {}
//int num() {}

void foo() {
s1.temp = 5;
s1.temp = 7;
}

void bar(int a) {}
//void bar(int a) {}

run {
if(s1.v == 5 && s2.v == 6) {
Expand Down
12 changes: 5 additions & 7 deletions res/universal/res/include/IntegerChannel.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package include;

public final class IntegerChannel {
public final class Channel {

private boolean transfering;

private int exchangeValue;
private MessageType exchangeValue;

public IntegerChannel() {
public Channel() {
transfering = true;
}

public synchronized void writeValue(int v) {
public synchronized void writeValue(MessageType v) {
while (!transfering) {
try {
wait();
Expand All @@ -23,7 +21,7 @@ public synchronized void writeValue(int v) {
notify();
}

public synchronized int readValue() {
public synchronized MessageType readValue() {
while (transfering) {
try {
wait();
Expand Down
5 changes: 3 additions & 2 deletions src/col/vct/col/ast/Node.scala
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ final case class TAnyClass[G]()(implicit val o: Origin = DiagnosticOrigin) exten
final case class TAxiomatic[G](adt: Ref[G, AxiomaticDataType[G]], args: Seq[Type[G]])(implicit val o: Origin = DiagnosticOrigin) extends DeclaredType[G] with TAxiomaticImpl[G]
final case class TEnum[G](enum: Ref[G, Enum[G]])(implicit val o: Origin = DiagnosticOrigin) extends DeclaredType[G]
final case class TProverType[G](ref: Ref[G, ProverType[G]])(implicit val o: Origin = DiagnosticOrigin) extends DeclaredType[G] with TProverTypeImpl[G]
final case class TVeyMontChannel[G](channelType: String)(implicit val o: Origin = DiagnosticOrigin) extends DeclaredType[G] with TVeyMontChannelImpl[G]

sealed trait ParRegion[G] extends NodeFamily[G] with ParRegionImpl[G]
final case class ParParallel[G](regions: Seq[ParRegion[G]])(val blame: Blame[ParPreconditionFailed])(implicit val o: Origin) extends ParRegion[G] with ParParallelImpl[G]
Expand Down Expand Up @@ -672,7 +673,7 @@ final case class SuperType[G](left: Expr[G], right: Expr[G])(implicit val o: Ori
final case class IndeterminateInteger[G](min: Expr[G], max: Expr[G])(implicit val o: Origin) extends Expr[G] with IndeterminateIntegerImpl[G]

sealed trait AssignExpression[G] extends Expr[G] with AssignExpressionImpl[G]
final case class VeyMontCommExpression[G](receiver: Ref[G,VeyMontThread[G]], sender : Ref[G,VeyMontThread[G]], assign: Statement[G])(implicit val o: Origin) extends Statement[G] with VeyMontCommImpl[G]
final case class VeyMontCommExpression[G](receiver: Ref[G,VeyMontThread[G]], sender : Ref[G,VeyMontThread[G]], chanType: Type[G], assign: Statement[G])(implicit val o: Origin) extends Statement[G] with VeyMontCommImpl[G]
final case class VeyMontAssignExpression[G](thread : Ref[G,VeyMontThread[G]], assign: Statement[G])(implicit val o: Origin) extends Statement[G] with VeyMontAssignExpressionImpl[G]
final case class PreAssignExpression[G](target: Expr[G], value: Expr[G])(val blame: Blame[AssignFailed])(implicit val o: Origin) extends AssignExpression[G] with PreAssignExpressionImpl[G]
final case class PostAssignExpression[G](target: Expr[G], value: Expr[G])(val blame: Blame[AssignFailed])(implicit val o: Origin) extends AssignExpression[G] with PostAssignExpressionImpl[G]
Expand Down Expand Up @@ -1061,7 +1062,7 @@ sealed trait JavaClassDeclaration[G] extends ClassDeclaration[G] with JavaClassD
final class JavaSharedInitialization[G](val isStatic: Boolean, val initialization: Statement[G])(implicit val o: Origin) extends JavaClassDeclaration[G] with JavaSharedInitializationImpl[G]
final class JavaFields[G](val modifiers: Seq[JavaModifier[G]], val t: Type[G], val decls: Seq[JavaVariableDeclaration[G]])(implicit val o: Origin) extends JavaClassDeclaration[G] with JavaFieldsImpl[G]
final class JavaConstructor[G](val modifiers: Seq[JavaModifier[G]], val name: String, val parameters: Seq[JavaParam[G]], val typeParameters: Seq[Variable[G]], val signals: Seq[Type[G]], val body: Statement[G], val contract: ApplicableContract[G])(val blame: Blame[ConstructorFailure])(implicit val o: Origin) extends JavaClassDeclaration[G] with JavaConstructorImpl[G]
final class JavaParam[G](val modifiers: Seq[JavaModifier[G]], val name: String, val t: Type[G])(implicit val o: Origin) extends Declaration[G]
final class JavaParam[G](val modifiers: Seq[JavaModifier[G]], val name: String, val t: Type[G])(implicit val o: Origin) extends Declaration[G] with JavaParamImpl[G]

final class JavaMethod[G](val modifiers: Seq[JavaModifier[G]], val returnType: Type[G], val dims: Int, val name: String, val parameters: Seq[JavaParam[G]], val typeParameters: Seq[Variable[G]], val signals: Seq[Type[G]], val body: Option[Statement[G]], val contract: ApplicableContract[G])(val blame: Blame[CallableFailure])(implicit val o: Origin) extends JavaClassDeclaration[G] with JavaMethodImpl[G]
final class JavaAnnotationMethod[G](val returnType: Type[G], val name: String, val default: Option[Expr[G]])(implicit val o: Origin) extends JavaClassDeclaration[G] with JavaAnnotationMethodImpl[G]
Expand Down
2 changes: 1 addition & 1 deletion src/col/vct/col/ast/lang/JavaFieldsImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ trait JavaFieldsImpl[G] { this: JavaFields[G] =>
override def isStatic = modifiers.contains(JavaStatic[G]())

override def layout(implicit ctx: Ctx): Doc =
Doc.lspread(modifiers) <> t <+> Doc.spread(decls) <> ";"
Doc.rspread(modifiers) <> t <+> Doc.spread(decls) <> ";"
}
2 changes: 1 addition & 1 deletion src/col/vct/col/ast/lang/JavaLocalDeclarationImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import vct.col.print.{Ctx, Doc, Group}

trait JavaLocalDeclarationImpl[G] { this: JavaLocalDeclaration[G] =>
override def layout(implicit ctx: Ctx): Doc =
Group(Doc.lspread(modifiers) <> t <+> Doc.args(decls))
Group(Doc.rspread(modifiers) <> t <+> Doc.args(decls))
}
2 changes: 1 addition & 1 deletion src/col/vct/col/ast/lang/JavaMethodImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ trait JavaMethodImpl[G] extends Declarator[G] { this: JavaMethod[G] =>
Doc.stack(Seq(
contract,
Group(Group(Group(
Doc.lspread(modifiers) <>
Doc.rspread(modifiers) <>
(if(typeParameters.isEmpty) Empty else Text("<") <> Doc.args(typeParameters) <> ">" <+> Empty) <>
returnType <+> name <> "[]".repeat(dims)) <> "(" <> Doc.args(parameters) <> ")") <>
(if(signals.isEmpty) Empty else Empty <>> Group(Text("throws") <+> Doc.args(signals)))
Expand Down
9 changes: 9 additions & 0 deletions src/col/vct/col/ast/lang/JavaParamImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package vct.col.ast.lang

import vct.col.ast.JavaParam
import vct.col.print.{Ctx, Doc, Text}

trait JavaParamImpl[G] { this: JavaParam[G] =>
override def layout(implicit ctx: Ctx): Doc = t.show <+> name

}
2 changes: 2 additions & 0 deletions src/col/vct/col/ast/type/TUnionImpl.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package vct.col.ast.`type`

import vct.col.ast.TUnion
import vct.col.print.{Ctx, Doc}

trait TUnionImpl[G] { this: TUnion[G] =>
override def layout(implicit ctx: Ctx): Doc = Doc.fold(types)(_ <+> "|" <+> _)

}
9 changes: 9 additions & 0 deletions src/col/vct/col/ast/type/TVeyMontChannelImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package vct.col.ast.`type`

import vct.col.ast.TVeyMontChannel
import vct.col.print.{Ctx, Doc, Text}

trait TVeyMontChannelImpl[G] { this: TVeyMontChannel[G] =>
override def layout(implicit ctx: Ctx): Doc =
Text(this.channelType)
}
2 changes: 1 addition & 1 deletion src/col/vct/col/typerules/CoercingRewriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1625,7 +1625,7 @@ abstract class CoercingRewriter[Pre <: Generation]() extends AbstractRewriter[Pr
case w @ WandApply(assn) => WandApply(res(assn))(w.blame)
case w @ WandPackage(expr, stat) => WandPackage(res(expr), stat)(w.blame)
case VeyMontAssignExpression(t,a) => VeyMontAssignExpression(t,a)
case VeyMontCommExpression(r,s,a) => VeyMontCommExpression(r,s,a)
case VeyMontCommExpression(r,s,t,a) => VeyMontCommExpression(r,s,t,a)
}
}

Expand Down
19 changes: 17 additions & 2 deletions src/main/vct/importer/Util.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package vct.importer

import hre.io.Readable
import vct.col.ast.Program
import vct.col.ast.{JavaClass, JavaNamespace, Program}
import vct.col.origin.{Blame, VerificationFailure}
import vct.col.rewrite.Disambiguate
import vct.main.stages.Resolution
import vct.parsers.ColPVLParser
import vct.parsers.{ColJavaParser, ColPVLParser}
import vct.parsers.transform.{ConstantBlameProvider, ReadableOriginProvider}
import vct.result.VerificationError.UserError

Expand All @@ -27,4 +27,19 @@ case object Util {
val unambiguousProgram: Program[_] = Disambiguate().dispatch(context.tasks.head.program)
unambiguousProgram.asInstanceOf[Program[G]]
}

case class JavaLoadError(error: String) extends UserError {
override def code: String = "JavaClassLoadError"

override def text: String = error
}

def loadJavaClass[G](readable: Readable): JavaClass[G] =
ColJavaParser(ReadableOriginProvider(readable), ConstantBlameProvider(LibraryFileBlame)).parse(readable).decls match {
case Seq(javaNamespace: JavaNamespace[G]) => javaNamespace.declarations match {
case Seq(javaClass: JavaClass[G]) => javaClass
case seq => throw JavaLoadError("Expected to load exactly one Java class but found " + seq.size)
}
case seq => throw JavaLoadError("Expected to load exactly one Java name space but found " + seq.size)
}
}
2 changes: 1 addition & 1 deletion src/main/vct/main/modes/VeyMont.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ object VeyMont extends LazyLogging {

def verifyWithOptions(options: Options, inputs: Seq[PathOrStd]) = {
val collector = BlameCollector()
val stages = Stages.veymontOfOptions(options, ConstantBlameProvider(collector))
val stages = Stages.veymontTransformationOfOptions(options, ConstantBlameProvider(collector))
logger.debug("Stages: " ++ stages.flatNames.map(_._1).mkString(", "))
stages.run(inputs) match {
case Left(value) => logger.error(value.text)
Expand Down
67 changes: 67 additions & 0 deletions src/main/vct/main/stages/CodeGeneration.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package vct.main.stages

import hre.progress.Progress
import hre.stages.Stage
import vct.col.ast.{JavaClass, Node, Verification}
import vct.col.print.Ctx
import vct.col.rewrite.{Generation, PrettifyBlocks, RewriterBuilder}
import vct.importer.Util
import vct.main.stages.Transformation.writeOutFunctions
import vct.options.Options
import vct.options.types.{Backend, PathOrStd}
import vct.rewrite.veymont.ParalleliseVeyMontThreads

object CodeGeneration {

private def writeOutFunctions(m: Map[String, PathOrStd]): Seq[(String, Verification[_ <: Generation] => Unit)] =
m.toSeq.map {
case (key, out) => (key, (program: Verification[_ <: Generation]) => out.write { writer =>
program.write(writer)(Ctx().namesIn(program))
})
}

def veymontGenerationOfOptions(options: Options): VeyMontGeneration =
options.backend match {
case Backend.Silicon | Backend.Carbon =>
VeyMontGeneration(
onBeforePassKey = writeOutFunctions(options.outputBeforePass),
onAfterPassKey = writeOutFunctions(options.outputAfterPass),
channelClass = Util.loadJavaClass(options.veymontChannel),
)
}
}

class CodeGeneration(val onBeforePassKey: Seq[(String, Verification[_ <: Generation] => Unit)],
val onAfterPassKey: Seq[(String, Verification[_ <: Generation] => Unit)],
val passes: Seq[RewriterBuilder]
) extends Stage[Verification[_ <: Generation], Verification[_ <: Generation]] {
override def friendlyName: String = "Generating VeyMont output"

override def progressWeight: Int = 1

override def run(input: Verification[_ <: Generation]): Verification[_ <: Generation] = {
var result: Verification[_ <: Generation] = input
Progress.foreach(passes, (pass: RewriterBuilder) => pass.key) { pass =>
onBeforePassKey.foreach {
case (key, action) => if (pass.key == key) action(result)
}

result = pass().dispatch(result)

onAfterPassKey.foreach {
case (key, action) => if (pass.key == key) action(result)
}

result = PrettifyBlocks().dispatch(result)
}
result
}

}

case class VeyMontGeneration(override val onBeforePassKey: Seq[(String, Verification[_ <: Generation] => Unit)] = Nil,
override val onAfterPassKey: Seq[(String, Verification[_ <: Generation] => Unit)] = Nil,
channelClass: JavaClass[_])
extends CodeGeneration(onBeforePassKey, onAfterPassKey, Seq(
ParalleliseVeyMontThreads.withArg(channelClass),
))
5 changes: 3 additions & 2 deletions src/main/vct/main/stages/Stages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ case object Stages {
.thenRun(ExpectedErrors.ofOptions(options))
}

def veymontOfOptions(options: Options, blameProvider: BlameProvider): Stages[Seq[Readable], Unit] = {
def veymontTransformationOfOptions(options: Options, blameProvider: BlameProvider): Stages[Seq[Readable], Unit] = {
Parsing.ofOptions(options, blameProvider)
.thenRun(Resolution.ofOptions(options, blameProvider))
.thenRun(Transformation.veymontOfOptions(options))
.thenRun(Transformation.veymontTransformationOfOptions(options))
.thenRun(CodeGeneration.veymontGenerationOfOptions(options))
.thenRun(Output.veymontOfOptions(options))
}

Expand Down
8 changes: 5 additions & 3 deletions src/main/vct/main/stages/Transformation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ object Transformation {
)
}

def veymontOfOptions(options: Options): Transformation =
def veymontTransformationOfOptions(options: Options): Transformation =
options.backend match {
case Backend.Silicon | Backend.Carbon =>
VeyMontTransformation(
onBeforePassKey = writeOutFunctions(options.outputBeforePass),
onAfterPassKey = writeOutFunctions(options.outputAfterPass)
onAfterPassKey = writeOutFunctions(options.outputAfterPass),
)
}
}
Expand Down Expand Up @@ -296,6 +296,8 @@ case class VeyMontTransformation(override val onBeforePassKey: Seq[(String, Veri
extends Transformation(onBeforePassKey, onAfterPassKey, Seq(
AddVeyMontAssignmentNodes,
AddVeyMontConditionNodes,
StructureCheck
StructureCheck,
))



2 changes: 2 additions & 0 deletions src/main/vct/options/Options.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import vct.main.BuildInfo
import vct.main.stages.Parsing.Language
import vct.options.types._
import vct.resources.Resources
import vct.resources.Resources.getVeymontChannel

import java.nio.file.{Path, Paths}
import scala.collection.mutable
Expand Down Expand Up @@ -387,6 +388,7 @@ case class Options

// VeyMont options
veymontOutput: Path = null, // required
veymontChannel: PathOrStd = PathOrStd.Path(getVeymontChannel),

// VeSUV options
vesuvOutput: Path = null,
Expand Down
1 change: 1 addition & 0 deletions src/main/vct/resources/Resources.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ case object Resources {
def getCcPath: Path = Paths.get("clang")
def getCPPcPath: Path = Paths.get("clang++")
def getSystemCConfig: Path = getResource("/systemc/config")
def getVeymontChannel: Path = getResource("/include/IntegerChannel.java")
}
12 changes: 10 additions & 2 deletions src/rewrite/vct/rewrite/veymont/AddVeyMontAssignmentNodes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,16 @@ case class AddVeyMontAssignmentNodes[Pre <: Generation]() extends Rewriter[Pre]
if (derefs.isEmpty)
new VeyMontAssignExpression[Post](succ(receiver), rewriteDefault(a))(a.o)
else if (derefs.size == 1) {
val sender = getAssignmentSender(derefs.head)
new VeyMontCommExpression[Post](succ(receiver), succ(sender), rewriteDefault(a))(a.o)
val thread = derefs.head.obj match {
case t: DerefVeyMontThread[Pre] => t
case _ => throw AddVeyMontAssignmentError(a.value, "The value of this assignment is expected to be a Deref of a thread!")
}
if(thread.ref.decl == receiver)
new VeyMontAssignExpression[Post](succ(receiver),rewriteDefault(a))(a.o)
else {
val sender = getAssignmentSender(derefs.head)
new VeyMontCommExpression[Post](succ(receiver), succ(sender), dispatch(derefs.head.ref.decl.t), rewriteDefault(a))(a.o)
}
} else throw AddVeyMontAssignmentError(a.value, "The value of this assignment is not allowed to refer to multiple threads!")
}

Expand Down
8 changes: 8 additions & 0 deletions src/rewrite/vct/rewrite/veymont/ChannelInfo.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package vct.rewrite.veymont

import vct.col.ast.{Type, VeyMontCommExpression}
import vct.col.rewrite.Generation

class ChannelInfo[Pre <: Generation](val comExpr: VeyMontCommExpression[Pre], val channelType: Type[Pre], val channelName: String) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package vct.rewrite.veymont

import vct.col.ast.{Assign, Deref, InstanceField, JavaClass}
import vct.col.rewrite.{Generation, Rewritten}

class ParallelCommExprBuildingBlocks[Pre <: Generation](val channelField: InstanceField[Rewritten[Pre]], val channelClass: JavaClass[Rewritten[Pre]],
val thisChanField: Deref[Rewritten[Pre]], val assign: Assign[Pre] ) {

}
Loading
Loading