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