diff --git a/kmir/pyproject.toml b/kmir/pyproject.toml
index a15931f5a..0e334eac2 100644
--- a/kmir/pyproject.toml
+++ b/kmir/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "kmir"
-version = "0.3.157"
+version = "0.3.158"
description = ""
requires-python = "~=3.10"
dependencies = [
diff --git a/kmir/src/kmir/__init__.py b/kmir/src/kmir/__init__.py
index 11b8242a1..e7190a888 100644
--- a/kmir/src/kmir/__init__.py
+++ b/kmir/src/kmir/__init__.py
@@ -1,3 +1,3 @@
from typing import Final
-VERSION: Final = '0.3.157'
+VERSION: Final = '0.3.158'
diff --git a/kmir/src/kmir/kdist/mir-semantics/rt/data.md b/kmir/src/kmir/kdist/mir-semantics/rt/data.md
index e65426e32..82c265772 100644
--- a/kmir/src/kmir/kdist/mir-semantics/rt/data.md
+++ b/kmir/src/kmir/kdist/mir-semantics/rt/data.md
@@ -329,10 +329,12 @@ In contrast to regular write operations, the value does not have to be _mutable_
rule VAL:TypedLocal ~> #markMoved(OLDLOCAL, local(I), PROJECTIONS) ~> CONT
=>
- #projectedUpdate(toLocal(I), OLDLOCAL, PROJECTIONS, Moved, .Contexts, true)
+ #projectedUpdate(#readProjection(toLocal(I), OLDLOCAL, PROJECTIONS, .Contexts, STACK, LOCALS), Moved, true)
~> VAL
~> CONT
+ STACK
+ LOCALS
[preserves-definedness] // projections already used when reading
```
@@ -400,13 +402,13 @@ The `#setLocalValue` operation writes a `TypedLocal` value to a given `Place` wi
Write operations to places that include (a chain of) projections are handled by a special rewrite symbol `#projectedUpdate`.
```k
- syntax KItem ::= #projectedUpdate ( WriteTo , TypedLocal, ProjectionElems, TypedLocal, Contexts , Bool )
+ syntax KItem ::= #projectedUpdate ( ProjectedUpdate , TypedLocal , Bool )
rule #setLocalValue(place(local(I), PROJ), VAL)
- =>
- #projectedUpdate(toLocal(I), {LOCALS[I]}:>TypedLocal, PROJ, VAL, .Contexts, false)
+ => #projectedUpdate(#readProjection(toLocal(I), {LOCALS[I]}:>TypedLocal, PROJ, .Contexts, STACK, LOCALS), VAL, false)
...
+ STACK
LOCALS
requires 0 <=Int I
andBool I VAL
[preserves-definedness]
- rule #buildUpdate(VAL, CtxField(TY, IDX, ARGS, I) CTXS)
- => #buildUpdate(typedValue(Aggregate(IDX, ARGS[I <- VAL]), TY, mutabilityMut), CTXS)
+ rule #buildUpdate(VAL, CtxField(TY, IDX, ARGS, I, MUT) CTXS)
+ => #buildUpdate(typedValue(Aggregate(IDX, ARGS[I <- VAL]), TY, MUT), CTXS)
[preserves-definedness] // valid list indexing checked upon context construction
- rule #buildUpdate(VAL, CtxIndex(TY, ELEMS, I) CTXS)
- => #buildUpdate(typedValue(Range(ELEMS[I <- VAL]), TY, mutabilityMut), CTXS)
+ rule #buildUpdate(VAL, CtxIndex(TY, ELEMS, I, MUT) CTXS)
+ => #buildUpdate(typedValue(Range(ELEMS[I <- VAL]), TY, MUT), CTXS)
[preserves-definedness] // valid list indexing checked upon context construction
- rule #projectedUpdate(
- DEST,
- typedValue(Aggregate(IDX, ARGS), TY, MUT),
- projectionElemField(fieldIdx(I), _) PROJS,
- UPDATE,
- CTXTS,
- FORCE
- ) =>
- #projectedUpdate(DEST, {ARGS[I]}:>TypedLocal, PROJS, UPDATE, CtxField(TY, IDX, ARGS, I) CTXTS, FORCE)
- ...
-
+ syntax ProjectedUpdate ::= #readProjection(WriteTo, TypedLocal, ProjectionElems, Contexts, List, List) [function] // total
+ | ProjectedUpdate(WriteTo, TypedValue, Contexts)
+ // ----------------------------------------------------------------------
+ rule #readProjection(
+ _DEST,
+ typedValue(Aggregate(IDX, ARGS), TY, MUT) => {ARGS[I]}:>TypedLocal,
+ projectionElemField(fieldIdx(I), TY) PROJS => PROJS,
+ CTXTS => CtxField(TY, IDX, ARGS, I, MUT) CTXTS,
+ _STACK,
+ _LOCALS
+ )
requires 0 <=Int I
andBool I #projectedUpdate(
- DEST,
- typedValue(Range(ELEMENTS), TY, MUT),
- projectionElemIndex(local(LOCAL)) PROJS,
- UPDATE,
- CTXTS,
- FORCE
- )
- =>
- #projectedUpdate(
- DEST,
- {ELEMENTS[#expectUsize({LOCALS[LOCAL]}:>TypedValue)]}:>TypedValue,
- PROJS,
- UPDATE,
- CtxIndex(TY, ELEMENTS, #expectUsize({LOCALS[LOCAL]}:>TypedValue)) CTXTS,
- FORCE)
- ...
-
- LOCALS
+ rule #readProjection(
+ _DEST,
+ typedValue(Range(ELEMENTS), TY, MUT) => {ELEMENTS[#expectUsize({LOCALS[LOCAL]}:>TypedValue)]}:>TypedValue,
+ projectionElemIndex(local(LOCAL)) PROJS => PROJS,
+ CTXTS => CtxIndex(TY, ELEMENTS, #expectUsize({LOCALS[LOCAL]}:>TypedValue), MUT) CTXTS,
+ _STACK,
+ LOCALS
+ )
requires 0 <=Int LOCAL
andBool LOCAL TypedValue)
andBool #expectUsize({LOCALS[LOCAL]}:>TypedValue) TypedValue)])
- andBool (FORCE orBool MUT ==K mutabilityMut)
[preserves-definedness] // index checked, valid Int can be read, ELEMENT indexable and writeable or forced
- rule #projectedUpdate(
- DEST,
- typedValue(Range(ELEMENTS), TY, MUT),
- projectionElemConstantIndex(OFFSET:Int, _MINLEN, false) PROJS,
- UPDATE,
- CTXTS,
- FORCE
- )
- =>
- #projectedUpdate(
- DEST,
- {ELEMENTS[OFFSET]}:>TypedValue,
- PROJS,
- UPDATE,
- CtxIndex(TY, ELEMENTS, OFFSET) CTXTS,
- FORCE)
- ...
-
+ rule #readProjection(
+ _DEST,
+ typedValue(Range(ELEMENTS), TY, MUT) => {ELEMENTS[OFFSET]}:>TypedValue,
+ projectionElemConstantIndex(OFFSET:Int, _MINLEN, false) PROJS => PROJS,
+ CTXTS => CtxIndex(TY, ELEMENTS, OFFSET, MUT) CTXTS,
+ _STACK,
+ _LOCALS
+ )
requires 0 <=Int OFFSET
andBool OFFSET #projectedUpdate(
- DEST,
- typedValue(Range(ELEMENTS), TY, MUT),
- projectionElemConstantIndex(OFFSET:Int, MINLEN, true) PROJS, // from end
- UPDATE,
- CTXTS,
- FORCE
- )
- =>
- #projectedUpdate(
- DEST,
- {ELEMENTS[OFFSET]}:>TypedValue,
- PROJS,
- UPDATE,
- CtxIndex(TY, ELEMENTS, MINLEN -Int OFFSET) CTXTS,
- FORCE)
- ...
-
+ rule #readProjection(
+ _DEST,
+ typedValue(Range(ELEMENTS), TY, MUT) => {ELEMENTS[OFFSET]}:>TypedValue,
+ projectionElemConstantIndex(OFFSET:Int, MINLEN, true) PROJS => PROJS,
+ CTXTS => CtxIndex(TY, ELEMENTS, MINLEN -Int OFFSET, MUT) CTXTS,
+ _STACK,
+ _LOCALS
+ )
requires 0 #projectedUpdate(
- _DEST,
- typedValue(Reference(OFFSET, place(LOCAL, PLACEPROJ), MUT), _, _),
- projectionElemDeref PROJS,
- UPDATE,
- _CTXTS,
- FORCE
- )
- =>
- #projectedUpdate(
- toStack(OFFSET, LOCAL),
- #localFromFrame({STACK[OFFSET -Int 1]}:>StackFrame, LOCAL, OFFSET),
- appendP(PLACEPROJ, PROJS), // apply reference projections first, then rest
- UPDATE,
- .Contexts, // previous contexts obsolete
- FORCE
- )
- ...
-
- STACK
+ rule #readProjection(
+ _DEST => toStack(OFFSET, LOCAL),
+ typedValue(Reference(OFFSET, place(LOCAL, PLACEPROJ), _), _, _),
+ projectionElemDeref PROJS => appendP(PLACEPROJ, PROJS),
+ _CTXTS => .Contexts,
+ STACK,
+ _LOCALS
+ )
requires 0 #projectedUpdate(
- _DEST,
- typedValue(Reference(OFFSET, place(local(I), PLACEPROJ), MUT), _, _),
- projectionElemDeref PROJS,
- UPDATE,
- _CTXTS,
- FORCE
- )
- =>
- #projectedUpdate(
- toLocal(I),
- {LOCALS[I]}:>TypedLocal,
- appendP(PLACEPROJ, PROJS), // apply reference projections first, then rest
- UPDATE,
- .Contexts, // previous contexts obsolete
- FORCE
- )
- ...
-
- LOCALS
+ rule #readProjection(
+ _DEST => toLocal(I),
+ typedValue(Reference(OFFSET, place(local(I), PLACEPROJ), _), _, _) => {LOCALS[I]}:>TypedLocal,
+ projectionElemDeref PROJS => appendP(PLACEPROJ, PROJS),
+ _CTXTS => .Contexts,
+ _STACK,
+ LOCALS
+ )
requires OFFSET ==Int 0
andBool 0 <=Int I
andBool I #projectedUpdate(toLocal(I), _ORIGINAL, .ProjectionElems, NEW, CONTEXTS, false)
- =>
- #setLocalValue(place(local(I), .ProjectionElems), #buildUpdate(NEW, CONTEXTS))
- ...
-
- [preserves-definedness] // valid conmtext ensured upon context construction
+ rule #readProjection(DEST, TV:TypedValue, .ProjectionElems, CONTEXTS, _, _)
+ => ProjectedUpdate(DEST, TV, CONTEXTS)
- rule #projectedUpdate(toLocal(I), _ORIGINAL, .ProjectionElems, NEW, CONTEXTS, true)
- =>
- #forceSetLocal(local(I), #buildUpdate(NEW, CONTEXTS))
+ rule #projectedUpdate(ProjectedUpdate(toLocal(I), typedValue(_, _, MUT), CONTEXTS), NEW, FORCE)
+ => #forceSetLocal(local(I), #buildUpdate(NEW, CONTEXTS))
...
-
+
+ requires MUT ==K mutabilityMut orBool FORCE
[preserves-definedness] // valid conmtext ensured upon context construction
syntax KItem ::= #forceSetLocal ( Local , TypedLocal )
// #forceSetLocal sets the given value unconditionally (to write Moved values)
- rule #forceSetLocal(local(I), VALUE)
- =>
- .K
- ...
-
+ rule #forceSetLocal(local(I), VALUE) => .K ...
LOCALS => LOCALS[I <- VALUE]
requires 0 <=Int I
andBool I #projectedUpdate(toStack(FRAME, local(I)), _ORIGINAL, .ProjectionElems, NEW, CONTEXTS, _) => .K ...
- STACK
- =>
- STACK[(FRAME -Int 1) <-
- #updateStackLocal({STACK[FRAME -Int 1]}:>StackFrame, I, #buildUpdate(NEW, CONTEXTS))
- ]
-
+ rule #projectedUpdate(ProjectedUpdate(toStack(FRAME, local(I)), typedValue(_, _, mutabilityMut), CONTEXTS), NEW, _) => .K ...
+ STACK => STACK[(FRAME -Int 1) <- #updateStackLocal({STACK[FRAME -Int 1]}:>StackFrame, I, #buildUpdate(NEW, CONTEXTS)) ]
requires 0