Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
61 changes: 30 additions & 31 deletions models/src/main/scala/coop/rchain/models/rholang/implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ object implicits {
case ETupleBody(e) => e.connectiveUsed
case ESetBody(e) => e.connectiveUsed
case EMapBody(e) => e.connectiveUsed
case EVarBody(EVar(v)) => VarLocallyFree.connectiveUsed(v)
case EVarBody(EVar(v)) => VarInstanceLocallyFree.connectiveUsed(v.varInstance)
case ENotBody(ENot(p)) => p.connectiveUsed
case ENegBody(ENeg(p)) => p.connectiveUsed
case EMultBody(EMult(p1, p2)) => p1.connectiveUsed || p2.connectiveUsed
Expand Down Expand Up @@ -436,7 +436,7 @@ object implicits {
case ETupleBody(e) => e.locallyFree
case ESetBody(e) => e.locallyFree.value
case EMapBody(e) => e.locallyFree.value
case EVarBody(EVar(v)) => VarLocallyFree.locallyFree(v, depth)
case EVarBody(EVar(v)) => VarInstanceLocallyFree.locallyFree(v.varInstance, depth)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove all depth from this file, e.g. here or from prepend methods. But this will require a lot of changes in the Reducer, so I can do it while working on new types.

case ENotBody(ENot(p)) => p.locallyFree
case ENegBody(ENeg(p)) => p.locallyFree
case EMultBody(EMult(p1, p2)) => p1.locallyFree | p2.locallyFree
Expand Down Expand Up @@ -468,30 +468,6 @@ object implicits {
def locallyFree(n: New, depth: Int) = n.locallyFree
}

implicit val VarInstanceLocallyFree: HasLocallyFree[VarInstance] =
new HasLocallyFree[VarInstance] {
def connectiveUsed(v: VarInstance) =
v match {
case BoundVar(_) => false
case FreeVar(_) => true
case Wildcard(_) => true
case VarInstance.Empty => false
}

def locallyFree(v: VarInstance, depth: Int) =
v match {
case BoundVar(index) => if (depth == 0) BitSet(index) else BitSet()
case FreeVar(_) => BitSet()
case Wildcard(_) => BitSet()
case VarInstance.Empty => BitSet()
}
}

implicit val VarLocallyFree: HasLocallyFree[Var] = new HasLocallyFree[Var] {
def connectiveUsed(v: Var) = VarInstanceLocallyFree.connectiveUsed(v.varInstance)
def locallyFree(v: Var, depth: Int) = VarInstanceLocallyFree.locallyFree(v.varInstance, depth)
}

implicit val ReceiveLocallyFree: HasLocallyFree[Receive] =
new HasLocallyFree[Receive] {
def connectiveUsed(r: Receive) = r.connectiveUsed
Expand All @@ -501,12 +477,12 @@ object implicits {
implicit val ReceiveBindLocallyFree: HasLocallyFree[ReceiveBind] =
new HasLocallyFree[ReceiveBind] {
def connectiveUsed(rb: ReceiveBind) =
ParLocallyFree.connectiveUsed(rb.source)
rb.source.connectiveUsed

def locallyFree(rb: ReceiveBind, depth: Int) =
ParLocallyFree.locallyFree(rb.source, depth) |
rb.source.locallyFree |
rb.patterns.foldLeft(BitSet()) { (acc, pat) =>
acc | ParLocallyFree.locallyFree(pat, depth + 1)
acc | pat.locallyFree
}
}

Expand All @@ -520,9 +496,32 @@ object implicits {
new HasLocallyFree[MatchCase] {
def connectiveUsed(mc: MatchCase) = mc.source.connectiveUsed
def locallyFree(mc: MatchCase, depth: Int) =
mc.source.locallyFree | ParLocallyFree.locallyFree(mc.pattern, depth + 1)
mc.source.locallyFree | mc.pattern.locallyFree
}

// Locally free is about variables so here is how they are collected

// Variable declaration
implicit val VarInstanceLocallyFree: HasLocallyFree[VarInstance] =
new HasLocallyFree[VarInstance] {
def connectiveUsed(v: VarInstance) =
v match {
case BoundVar(_) => false
case FreeVar(_) => true
case Wildcard(_) => true
case VarInstance.Empty => false // This should throw error
}

def locallyFree(v: VarInstance, depth: Int) =
v match {
case BoundVar(index) => if (depth == 0) BitSet(index) else BitSet()
case FreeVar(_) => BitSet()
case Wildcard(_) => BitSet()
case VarInstance.Empty => BitSet() // This should throw error
}
}

// Variable reference
implicit val ConnectiveLocallyFree: HasLocallyFree[Connective] =
new HasLocallyFree[Connective] {
def connectiveUsed(conn: Connective) =
Expand All @@ -537,7 +536,7 @@ object implicits {
case _: ConnString => true
case _: ConnUri => true
case _: ConnByteArray => true
case ConnectiveInstance.Empty => false
case ConnectiveInstance.Empty => false // This should throw error
}
def locallyFree(conn: Connective, depth: Int) =
conn.connectiveInstance match {
Expand Down
2 changes: 1 addition & 1 deletion project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ object Dependencies {
val kamonZipkin = "io.kamon" %% "kamon-zipkin" % kamonVersion
val lightningj = ("org.lightningj" % "lightningj" % "0.5.2-Beta")
.intransitive() //we only use the lib for one util class (org.lightningj.util.ZBase32) that has no dependencies
val lmdbjava = "org.lmdbjava" % "lmdbjava" % "0.8.2"
val lmdbjava = "org.lmdbjava" % "lmdbjava" % "0.8.3"
val logbackClassic = "ch.qos.logback" % "logback-classic" % "1.4.6"
val logstashLogback = "net.logstash.logback" % "logstash-logback-encoder" % "6.6"
val lz4 = "org.lz4" % "lz4-java" % "1.7.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ class DebruijnInterpreter[M[_]: Sync: Parallel: CostStateRef](
def addToEnv(env: Env[Par], freeMap: Map[Int, Par], freeCount: Int): Env[Par] =
Range(0, freeCount).foldLeft(env)((acc, e) => acc.put(freeMap.getOrElse(e, Par())))

def firstMatch(target: Par, cases: Seq[MatchCase])(implicit env: Env[Par]): M[Unit] = {
def firstMatch(target: Par, cases: Seq[MatchCase], env: Env[Par]): M[Unit] = {
def firstMatchM(
state: (Par, Seq[MatchCase])
): M[Either[(Par, Seq[MatchCase]), Unit]] = {
Expand Down Expand Up @@ -383,7 +383,7 @@ class DebruijnInterpreter[M[_]: Sync: Parallel: CostStateRef](
evaledTarget <- evalExpr(mat.target)
// TODO(kyle): Make the matcher accept an environment, instead of substituting it.
substTarget <- substituteAndCharge[Par, M](evaledTarget, depth = 0, env)
_ <- firstMatch(substTarget, mat.cases)
_ <- firstMatch(substTarget, mat.cases, env)
} yield ()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,13 @@ object CollectionNormalizeMatcher {
}
}
.map { folded =>
val resultKnownFree = folded._2
val remainderConnectiveUsed = remainder.exists(HasLocallyFree[Var].connectiveUsed(_))
val resultKnownFree = folded._2
val remainderConnectiveUsed =
remainder.exists(v => VarInstanceLocallyFree.connectiveUsed(v.varInstance))
val remainderLocallyFree =
remainder.map(HasLocallyFree[Var].locallyFree(_, depth = 0)).getOrElse(BitSet())
remainder
.map(r => VarInstanceLocallyFree.locallyFree(r.varInstance, depth = 0))
.getOrElse(BitSet())

CollectVisitOutputs(
ParMap(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ object PContrNormalizer {
(
result.par +: acc._1,
result.freeMap,
acc._3 | ParLocallyFree
.locallyFree(result.par, input.boundMapChain.depth + 1)
acc._3 | result.par.locallyFree
)
)
}
Expand Down Expand Up @@ -88,13 +87,11 @@ object PContrNormalizer {
persistent = true,
peek = false,
bindCount = boundCount,
locallyFree = ParLocallyFree
.locallyFree(nameMatchResult.par, input.boundMapChain.depth) | formalsResults._3
locallyFree = nameMatchResult.par.locallyFree | formalsResults._3
| (bodyResult.par.locallyFree
.rangeFrom(boundCount)
.map(x => x - boundCount)),
connectiveUsed = ParLocallyFree
.connectiveUsed(nameMatchResult.par) || bodyResult.par.connectiveUsed
connectiveUsed = nameMatchResult.par.connectiveUsed || bodyResult.par.connectiveUsed
)
),
bodyResult.freeMap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ object PInputNormalizer {
(
vectorPar :+ par,
knownFree,
locallyFree | ParLocallyFree.locallyFree(par, input.boundMapChain.depth),
connectiveUsed || ParLocallyFree.connectiveUsed(par)
locallyFree | par.locallyFree,
connectiveUsed || par.connectiveUsed
)
}
}
Expand All @@ -179,8 +179,7 @@ object PInputNormalizer {
(
vectorPar :+ par,
knownFree,
locallyFree | ParLocallyFree
.locallyFree(par, input.boundMapChain.depth + 1)
locallyFree | par.locallyFree
).pure[F]
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,7 @@ object PLetNormalizer {
(
par +: vectorPar,
updatedKnownFree,
// Use input.env.depth + 1 because the pattern was evaluated w.r.t input.env.push,
// and more generally because locally free variables become binders in the pattern position
locallyFree | ParLocallyFree
.locallyFree(par, input.boundMapChain.depth + 1)
locallyFree | par.locallyFree
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ object PSendNormalizer {
nameMatchResult.par,
dataResults._1,
persistent,
ParLocallyFree
.locallyFree(nameMatchResult.par, input.boundMapChain.depth) | dataResults._3,
ParLocallyFree.connectiveUsed(nameMatchResult.par) || dataResults._4
nameMatchResult.par.locallyFree | dataResults._3,
nameMatchResult.par.connectiveUsed || dataResults._4
)
),
dataResults._2.freeMap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,17 @@ object SpatialMatcher extends SpatialMatcherInstances {
case None =>
MonoidK[F].empty[Seq[T]]
case Some(Var(FreeVar(level))) => {
def freeCheck(trem: Seq[T], level: Int, acc: Seq[T]): F[Seq[T]] =
def freeCheck(trem: Seq[T], acc: Seq[T]): F[Seq[T]] =
trem match {
case Nil => acc.pure[F]
case Nil => acc.pure[F]
case item +: rem =>
if (lft.locallyFree(item, 0).isEmpty)
freeCheck(rem, level, acc :+ item)
else
MonoidK[F].empty[Seq[T]]
// if (lft.locallyFree(item, 0).isEmpty)
// freeCheck(rem, acc :+ item)
// else
// MonoidK[F].empty[Seq[T]]
freeCheck(rem, acc :+ item)
}
freeCheck(trem, level, Vector.empty[T])
freeCheck(trem, Vector.empty[T])
}
case Some(Var(Wildcard(_))) => Seq.empty[T].pure[F]
case _ => MonoidK[F].empty[Seq[T]]
Expand Down Expand Up @@ -141,10 +142,11 @@ object SpatialMatcher extends SpatialMatcherInstances {
else if (plen == 0 && tlen == 0 && remainder.isEmpty)
().pure[F]
else if (plen == 0 && remainder.isDefined) {
if (tlist.forall(lf.locallyFree(_, 0).isEmpty))
handleRemainder[F, T](tlist, remainder.get, merger)
else
MonoidK[F].empty[Unit]
// if (tlist.forall(lf.locallyFree(_, 0).isEmpty))
// handleRemainder[F, T](tlist, remainder.get, merger)
// else
// MonoidK[F].empty[Unit]
handleRemainder[F, T](tlist, remainder.get, merger)
} else
listMatch[F, T](tlist, plist, merger, remainder, wildcard)

Expand All @@ -160,13 +162,13 @@ object SpatialMatcher extends SpatialMatcherInstances {
)(implicit lf: HasLocallyFree[T], sm: SpatialMatcher[F, T, T]): F[Unit] = {

sealed trait Pattern
final case class Term(term: T) extends Pattern
final case class Remainder(level: Int) extends Pattern
final case class Term(term: T) extends Pattern
final case class Remainder() extends Pattern

val remainderPatterns: Seq[Pattern] = remainder.fold(
Seq.empty[Pattern]
)(
level => Seq.fill(targets.size - patterns.size)(Remainder(level))
_ => Seq.fill(targets.size - patterns.size)(Remainder())
)
val allPatterns = remainderPatterns ++ patterns.map(Term)

Expand All @@ -180,10 +182,11 @@ object SpatialMatcher extends SpatialMatcherInstances {
} else {
spatialMatch(t, p)
}
case Remainder(_) =>
case Remainder() =>
//Remainders can't match non-concrete terms, because they can't be captured.
//They match everything that's concrete though.
Alternative_[F].guard(lf.locallyFree(t, 0).isEmpty)
// Alternative_[F].guard(lf.locallyFree(t, 0).isEmpty)
Alternative_[F].guard(true)
}
attemptOpt[F, FreeMap](isolateState[F, FreeMap](matchEffect))
}
Expand Down