Merged
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
33 changes: 0 additions & 33 deletions Check.lean

This file was deleted.

19 changes: 16 additions & 3 deletions Ix/Aiur/Stages/Codegen.lean
Original file line numberDiff line numberDiff line change
Expand Up@@ -635,8 +635,21 @@ private def emitUncBigUintDivMod (out : Nat) (a b : ValIdx) : Array RustStmt :=
declVal (out + 1) (.field (.var "__bu_qr") "1")
]

/-- `Op::Debug`: 0 outputs; println side effect. Skipped for now. -/
private def emitDebug : Array RustStmt := #[]
/-- `Op::Debug`: 0 outputs; println side effect, mirroring the bytecode
interpreter's `Op::Debug` arm (crates/aiur/src/execute.rs). Production
kernels contain no `dbg!`, so this emits nothing there; when probing
with `dbg!` it makes the (much faster) codegen kernel print the same
lines as `--interp bytecode`. -/
private def emitDebug (label : String) (args : Option (Array ValIdx)) : Array RustStmt :=
-- Escape the label for use inside a Rust format-string literal.
let esc := label.replace "\\" "\\\\" |>.replace "\"" "\\\""
|>.replace "{" "{{" |>.replace "}" "}}"
match args with
| none => #[.exprStmt (.lit s!"println!(\"{esc}\")")]
| some idxs =>
let holes := String.intercalate ", " (idxs.map (fun _ => "{}")).toList
let vals := String.intercalate ", " (idxs.map (s!"__v_{·}")).toList
#[.exprStmt (.lit s!"println!(\"{esc}: {holes}\", {vals})")]

/-- Top-level op dispatch. `out` = the first ValIdx for outputs;
callers must advance their counter by `Op.outputCount`. -/
Expand DownExpand Up@@ -670,7 +683,7 @@ def emitOp (out : Nat) (op : Op) : Array RustStmt :=
| .u32LessThan a b => emitU32LessThan out a b
| .u8RangeCheck i j => emitU8RangeCheck i j
| .unconstrainedBigUintDivMod a b => emitUncBigUintDivMod out a b
| .debug _ _ => emitDebug
| .debug label args => emitDebug label args

/-! ## Ctrl emission -/

Expand Down
2 changes: 1 addition & 1 deletion Ix/Cli/CheckCmd.lean
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/-
`ix check`: execute the IxVM Aiur kernel over a Lean or `.ixe`
environment, one constant at a time. Mirrors what `lake exe check` does.
environment, one constant at a time.
The Rust kernel typechecker that used to live under this name is now `ix check-rs`.

Usage shape:
Expand Down
98 changes: 98 additions & 0 deletions Ix/Cli/NameOfCmd.lean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
/-
`ix name-of <64-hex-addr> --ixe <path>`: resolve a content address
back to its Lean name(s) in an on-disk env.

A single address can carry MANY names: structurally equivalent
constants collapse to the same content address, and every such name
is registered against it in the env's `named` table. All of them are
printed, one per line.

If the address is not directly named (e.g. an anonymized Muts
block), scan the env for projection constants whose block field
points at it and print those projections' names — any of them
fast-repros the block via `ix check --ixe <path> <name>`.
-/
module
public import Cli
public import Std.Internal.UV.System
public import Ix.Address
public import Ix.Common
public import Ix.Environment
public import Ix.Ixon
public import Ix.Meta
public import Ix.Cli.NameResolve

public section

open Ix.Cli.NameResolve

namespace Ix.Cli.NameOfCmd

/-- Address → name(s). Direct hits come from filtering the env's
`named` table (the `addrToName` reverse index keeps only one name
per address, so it would silently drop structurally-equivalent
aliases); the projection scan is the fallback for unnamed blocks. -/
def nameLookup (ixonEnv : Ixon.Env) (addr : Address) : IO UInt32 := do
let mut found := 0
for (n, named) in ixonEnv.named do
if named.addr == addr then
IO.println (toString (ixNameToLeanName n))
found := found + 1
if found > 0 then
return 0
IO.eprintln s!"{addr} is not a named constant; \
scanning for projections into it..."
for (caddr, lc) in ixonEnv.consts do
let some c := lc.get? | continue
let blk? := match c.info with
| .iPrj p => some p.block
| .cPrj p => some p.block
| .rPrj p => some p.block
| .dPrj p => some p.block
| _ => none
if blk? == some addr then
let nm := match ixonEnv.getName? caddr with
| some n => toString (ixNameToLeanName n)
| none => s!"<unnamed {caddr}>"
IO.println nm
found := found + 1
if found == 0 then
IO.eprintln s!"error: no name or projection found for {addr}"
return 1
return 0

def runNameOfCmd (p : Cli.Parsed) : IO UInt32 := do
-- Suppress Rust-side `[compile_env]` scheduler noise; the only
-- signal this command emits is the name list on stdout.
Std.Internal.UV.System.osSetenv "IX_QUIET" "1"
let some addrArg := p.positionalArg? "addr"
| p.printError "error: must specify a 64-char hex address"; return 1
let argStr := addrArg.as! String
let some addr := Address.fromString argStr
| IO.eprintln s!"error: `{argStr}` is not a 64-char hex address"
return 1
let some path := (p.flag? "ixe").map (·.as! String)
| IO.eprintln "error: name-of requires --ixe <path>"
return 1
let bytes ← IO.FS.readBinFile path
let ixonEnv ← match Ixon.deEnvAnon bytes with
| .error e =>
IO.eprintln s!"error: failed to deserialize {path}: {e}"; return 1
| .ok env => pure env
nameLookup ixonEnv addr

end Ix.Cli.NameOfCmd

open Ix.Cli.NameOfCmd in
def nameOfCmd : Cli.Cmd := `[Cli|
"name-of" VIA runNameOfCmd;
"Resolve a content address back to its Lean name(s) in a `.ixe` env (may print several: structurally equivalent constants share an address)"

FLAGS:
"ixe" : String; "Path to a serialized `.ixe` env to resolve the address in (required)."

ARGS:
addr : String; "64-char hex content address to resolve. Prints every Lean.Name registered for it, one per line; for unnamed Muts blocks, prints the names of projection constants into the block instead."
]

end
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
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
33 changes: 0 additions & 33 deletions Check.lean

This file was deleted.

19 changes: 16 additions & 3 deletions Ix/Aiur/Stages/Codegen.lean
Original file line numberDiff line numberDiff line change
Expand Up@@ -635,8 +635,21 @@ private def emitUncBigUintDivMod (out : Nat) (a b : ValIdx) : Array RustStmt :=
declVal (out + 1) (.field (.var "__bu_qr") "1")
]

/-- `Op::Debug`: 0 outputs; println side effect. Skipped for now. -/
private def emitDebug : Array RustStmt := #[]
/-- `Op::Debug`: 0 outputs; println side effect, mirroring the bytecode
interpreter's `Op::Debug` arm (crates/aiur/src/execute.rs). Production
kernels contain no `dbg!`, so this emits nothing there; when probing
with `dbg!` it makes the (much faster) codegen kernel print the same
lines as `--interp bytecode`. -/
private def emitDebug (label : String) (args : Option (Array ValIdx)) : Array RustStmt :=
-- Escape the label for use inside a Rust format-string literal.
let esc := label.replace "\\" "\\\\" |>.replace "\"" "\\\""
|>.replace "{" "{{" |>.replace "}" "}}"
match args with
| none => #[.exprStmt (.lit s!"println!(\"{esc}\")")]
| some idxs =>
let holes := String.intercalate ", " (idxs.map (fun _ => "{}")).toList
let vals := String.intercalate ", " (idxs.map (s!"__v_{·}")).toList
#[.exprStmt (.lit s!"println!(\"{esc}: {holes}\", {vals})")]

/-- Top-level op dispatch. `out` = the first ValIdx for outputs;
callers must advance their counter by `Op.outputCount`. -/
Expand DownExpand Up@@ -670,7 +683,7 @@ def emitOp (out : Nat) (op : Op) : Array RustStmt :=
| .u32LessThan a b => emitU32LessThan out a b
| .u8RangeCheck i j => emitU8RangeCheck i j
| .unconstrainedBigUintDivMod a b => emitUncBigUintDivMod out a b
| .debug _ _ => emitDebug
| .debug label args => emitDebug label args

/-! ## Ctrl emission -/

Expand Down
2 changes: 1 addition & 1 deletion Ix/Cli/CheckCmd.lean
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/-
`ix check`: execute the IxVM Aiur kernel over a Lean or `.ixe`
environment, one constant at a time. Mirrors what `lake exe check` does.
environment, one constant at a time.
The Rust kernel typechecker that used to live under this name is now `ix check-rs`.

Usage shape:
Expand Down
98 changes: 98 additions & 0 deletions Ix/Cli/NameOfCmd.lean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
/-
`ix name-of <64-hex-addr> --ixe <path>`: resolve a content address
back to its Lean name(s) in an on-disk env.

A single address can carry MANY names: structurally equivalent
constants collapse to the same content address, and every such name
is registered against it in the env's `named` table. All of them are
printed, one per line.

If the address is not directly named (e.g. an anonymized Muts
block), scan the env for projection constants whose block field
points at it and print those projections' names — any of them
fast-repros the block via `ix check --ixe <path> <name>`.
-/
module
public import Cli
public import Std.Internal.UV.System
public import Ix.Address
public import Ix.Common
public import Ix.Environment
public import Ix.Ixon
public import Ix.Meta
public import Ix.Cli.NameResolve

public section

open Ix.Cli.NameResolve

namespace Ix.Cli.NameOfCmd

/-- Address → name(s). Direct hits come from filtering the env's
`named` table (the `addrToName` reverse index keeps only one name
per address, so it would silently drop structurally-equivalent
aliases); the projection scan is the fallback for unnamed blocks. -/
def nameLookup (ixonEnv : Ixon.Env) (addr : Address) : IO UInt32 := do
let mut found := 0
for (n, named) in ixonEnv.named do
if named.addr == addr then
IO.println (toString (ixNameToLeanName n))
found := found + 1
if found > 0 then
return 0
IO.eprintln s!"{addr} is not a named constant; \
scanning for projections into it..."
for (caddr, lc) in ixonEnv.consts do
let some c := lc.get? | continue
let blk? := match c.info with
| .iPrj p => some p.block
| .cPrj p => some p.block
| .rPrj p => some p.block
| .dPrj p => some p.block
| _ => none
if blk? == some addr then
let nm := match ixonEnv.getName? caddr with
| some n => toString (ixNameToLeanName n)
| none => s!"<unnamed {caddr}>"
IO.println nm
found := found + 1
if found == 0 then
IO.eprintln s!"error: no name or projection found for {addr}"
return 1
return 0

def runNameOfCmd (p : Cli.Parsed) : IO UInt32 := do
-- Suppress Rust-side `[compile_env]` scheduler noise; the only
-- signal this command emits is the name list on stdout.
Std.Internal.UV.System.osSetenv "IX_QUIET" "1"
let some addrArg := p.positionalArg? "addr"
| p.printError "error: must specify a 64-char hex address"; return 1
let argStr := addrArg.as! String
let some addr := Address.fromString argStr
| IO.eprintln s!"error: `{argStr}` is not a 64-char hex address"
return 1
let some path := (p.flag? "ixe").map (·.as! String)
| IO.eprintln "error: name-of requires --ixe <path>"
return 1
let bytes ← IO.FS.readBinFile path
let ixonEnv ← match Ixon.deEnvAnon bytes with
| .error e =>
IO.eprintln s!"error: failed to deserialize {path}: {e}"; return 1
| .ok env => pure env
nameLookup ixonEnv addr

end Ix.Cli.NameOfCmd

open Ix.Cli.NameOfCmd in
def nameOfCmd : Cli.Cmd := `[Cli|
"name-of" VIA runNameOfCmd;
"Resolve a content address back to its Lean name(s) in a `.ixe` env (may print several: structurally equivalent constants share an address)"

FLAGS:
"ixe" : String; "Path to a serialized `.ixe` env to resolve the address in (required)."

ARGS:
addr : String; "64-char hex content address to resolve. Prints every Lean.Name registered for it, one per line; for unnamed Muts blocks, prints the names of projection constants into the block instead."
]

end
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
33 changes: 0 additions & 33 deletions Check.lean

This file was deleted.

19 changes: 16 additions & 3 deletions Ix/Aiur/Stages/Codegen.lean
Original file line numberDiff line numberDiff line change
Expand Up@@ -635,8 +635,21 @@ private def emitUncBigUintDivMod (out : Nat) (a b : ValIdx) : Array RustStmt :=
declVal (out + 1) (.field (.var "__bu_qr") "1")
]

/-- `Op::Debug`: 0 outputs; println side effect. Skipped for now. -/
private def emitDebug : Array RustStmt := #[]
/-- `Op::Debug`: 0 outputs; println side effect, mirroring the bytecode
interpreter's `Op::Debug` arm (crates/aiur/src/execute.rs). Production
kernels contain no `dbg!`, so this emits nothing there; when probing
with `dbg!` it makes the (much faster) codegen kernel print the same
lines as `--interp bytecode`. -/
private def emitDebug (label : String) (args : Option (Array ValIdx)) : Array RustStmt :=
-- Escape the label for use inside a Rust format-string literal.
let esc := label.replace "\\" "\\\\" |>.replace "\"" "\\\""
|>.replace "{" "{{" |>.replace "}" "}}"
match args with
| none => #[.exprStmt (.lit s!"println!(\"{esc}\")")]
| some idxs =>
let holes := String.intercalate ", " (idxs.map (fun _ => "{}")).toList
let vals := String.intercalate ", " (idxs.map (s!"__v_{·}")).toList
#[.exprStmt (.lit s!"println!(\"{esc}: {holes}\", {vals})")]

/-- Top-level op dispatch. `out` = the first ValIdx for outputs;
callers must advance their counter by `Op.outputCount`. -/
Expand DownExpand Up@@ -670,7 +683,7 @@ def emitOp (out : Nat) (op : Op) : Array RustStmt :=
| .u32LessThan a b => emitU32LessThan out a b
| .u8RangeCheck i j => emitU8RangeCheck i j
| .unconstrainedBigUintDivMod a b => emitUncBigUintDivMod out a b
| .debug _ _ => emitDebug
| .debug label args => emitDebug label args

/-! ## Ctrl emission -/

Expand Down
2 changes: 1 addition & 1 deletion Ix/Cli/CheckCmd.lean
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/-
`ix check`: execute the IxVM Aiur kernel over a Lean or `.ixe`
environment, one constant at a time. Mirrors what `lake exe check` does.
environment, one constant at a time.
The Rust kernel typechecker that used to live under this name is now `ix check-rs`.

Usage shape:
Expand Down
98 changes: 98 additions & 0 deletions Ix/Cli/NameOfCmd.lean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
/-
`ix name-of <64-hex-addr> --ixe <path>`: resolve a content address
back to its Lean name(s) in an on-disk env.

A single address can carry MANY names: structurally equivalent
constants collapse to the same content address, and every such name
is registered against it in the env's `named` table. All of them are
printed, one per line.

If the address is not directly named (e.g. an anonymized Muts
block), scan the env for projection constants whose block field
points at it and print those projections' names — any of them
fast-repros the block via `ix check --ixe <path> <name>`.
-/
module
public import Cli
public import Std.Internal.UV.System
public import Ix.Address
public import Ix.Common
public import Ix.Environment
public import Ix.Ixon
public import Ix.Meta
public import Ix.Cli.NameResolve

public section

open Ix.Cli.NameResolve

namespace Ix.Cli.NameOfCmd

/-- Address → name(s). Direct hits come from filtering the env's
`named` table (the `addrToName` reverse index keeps only one name
per address, so it would silently drop structurally-equivalent
aliases); the projection scan is the fallback for unnamed blocks. -/
def nameLookup (ixonEnv : Ixon.Env) (addr : Address) : IO UInt32 := do
let mut found := 0
for (n, named) in ixonEnv.named do
if named.addr == addr then
IO.println (toString (ixNameToLeanName n))
found := found + 1
if found > 0 then
return 0
IO.eprintln s!"{addr} is not a named constant; \
scanning for projections into it..."
for (caddr, lc) in ixonEnv.consts do
let some c := lc.get? | continue
let blk? := match c.info with
| .iPrj p => some p.block
| .cPrj p => some p.block
| .rPrj p => some p.block
| .dPrj p => some p.block
| _ => none
if blk? == some addr then
let nm := match ixonEnv.getName? caddr with
| some n => toString (ixNameToLeanName n)
| none => s!"<unnamed {caddr}>"
IO.println nm
found := found + 1
if found == 0 then
IO.eprintln s!"error: no name or projection found for {addr}"
return 1
return 0

def runNameOfCmd (p : Cli.Parsed) : IO UInt32 := do
-- Suppress Rust-side `[compile_env]` scheduler noise; the only
-- signal this command emits is the name list on stdout.
Std.Internal.UV.System.osSetenv "IX_QUIET" "1"
let some addrArg := p.positionalArg? "addr"
| p.printError "error: must specify a 64-char hex address"; return 1
let argStr := addrArg.as! String
let some addr := Address.fromString argStr
| IO.eprintln s!"error: `{argStr}` is not a 64-char hex address"
return 1
let some path := (p.flag? "ixe").map (·.as! String)
| IO.eprintln "error: name-of requires --ixe <path>"
return 1
let bytes ← IO.FS.readBinFile path
let ixonEnv ← match Ixon.deEnvAnon bytes with
| .error e =>
IO.eprintln s!"error: failed to deserialize {path}: {e}"; return 1
| .ok env => pure env
nameLookup ixonEnv addr

end Ix.Cli.NameOfCmd

open Ix.Cli.NameOfCmd in
def nameOfCmd : Cli.Cmd := `[Cli|
"name-of" VIA runNameOfCmd;
"Resolve a content address back to its Lean name(s) in a `.ixe` env (may print several: structurally equivalent constants share an address)"

FLAGS:
"ixe" : String; "Path to a serialized `.ixe` env to resolve the address in (required)."

ARGS:
addr : String; "64-char hex content address to resolve. Prints every Lean.Name registered for it, one per line; for unnamed Muts blocks, prints the names of projection constants into the block instead."
]

end
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
33 changes: 0 additions & 33 deletions Check.lean

This file was deleted.

19 changes: 16 additions & 3 deletions Ix/Aiur/Stages/Codegen.lean
Original file line numberDiff line numberDiff line change
Expand Up@@ -635,8 +635,21 @@ private def emitUncBigUintDivMod (out : Nat) (a b : ValIdx) : Array RustStmt :=
declVal (out + 1) (.field (.var "__bu_qr") "1")
]

/-- `Op::Debug`: 0 outputs; println side effect. Skipped for now. -/
private def emitDebug : Array RustStmt := #[]
/-- `Op::Debug`: 0 outputs; println side effect, mirroring the bytecode
interpreter's `Op::Debug` arm (crates/aiur/src/execute.rs). Production
kernels contain no `dbg!`, so this emits nothing there; when probing
with `dbg!` it makes the (much faster) codegen kernel print the same
lines as `--interp bytecode`. -/
private def emitDebug (label : String) (args : Option (Array ValIdx)) : Array RustStmt :=
-- Escape the label for use inside a Rust format-string literal.
let esc := label.replace "\\" "\\\\" |>.replace "\"" "\\\""
|>.replace "{" "{{" |>.replace "}" "}}"
match args with
| none => #[.exprStmt (.lit s!"println!(\"{esc}\")")]
| some idxs =>
let holes := String.intercalate ", " (idxs.map (fun _ => "{}")).toList
let vals := String.intercalate ", " (idxs.map (s!"__v_{·}")).toList
#[.exprStmt (.lit s!"println!(\"{esc}: {holes}\", {vals})")]

/-- Top-level op dispatch. `out` = the first ValIdx for outputs;
callers must advance their counter by `Op.outputCount`. -/
Expand DownExpand Up@@ -670,7 +683,7 @@ def emitOp (out : Nat) (op : Op) : Array RustStmt :=
| .u32LessThan a b => emitU32LessThan out a b
| .u8RangeCheck i j => emitU8RangeCheck i j
| .unconstrainedBigUintDivMod a b => emitUncBigUintDivMod out a b
| .debug _ _ => emitDebug
| .debug label args => emitDebug label args

/-! ## Ctrl emission -/

Expand Down
2 changes: 1 addition & 1 deletion Ix/Cli/CheckCmd.lean
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/-
`ix check`: execute the IxVM Aiur kernel over a Lean or `.ixe`
environment, one constant at a time. Mirrors what `lake exe check` does.
environment, one constant at a time.
The Rust kernel typechecker that used to live under this name is now `ix check-rs`.

Usage shape:
Expand Down
98 changes: 98 additions & 0 deletions Ix/Cli/NameOfCmd.lean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
/-
`ix name-of <64-hex-addr> --ixe <path>`: resolve a content address
back to its Lean name(s) in an on-disk env.

A single address can carry MANY names: structurally equivalent
constants collapse to the same content address, and every such name
is registered against it in the env's `named` table. All of them are
printed, one per line.

If the address is not directly named (e.g. an anonymized Muts
block), scan the env for projection constants whose block field
points at it and print those projections' names — any of them
fast-repros the block via `ix check --ixe <path> <name>`.
-/
module
public import Cli
public import Std.Internal.UV.System
public import Ix.Address
public import Ix.Common
public import Ix.Environment
public import Ix.Ixon
public import Ix.Meta
public import Ix.Cli.NameResolve

public section

open Ix.Cli.NameResolve

namespace Ix.Cli.NameOfCmd

/-- Address → name(s). Direct hits come from filtering the env's
`named` table (the `addrToName` reverse index keeps only one name
per address, so it would silently drop structurally-equivalent
aliases); the projection scan is the fallback for unnamed blocks. -/
def nameLookup (ixonEnv : Ixon.Env) (addr : Address) : IO UInt32 := do
let mut found := 0
for (n, named) in ixonEnv.named do
if named.addr == addr then
IO.println (toString (ixNameToLeanName n))
found := found + 1
if found > 0 then
return 0
IO.eprintln s!"{addr} is not a named constant; \
scanning for projections into it..."
for (caddr, lc) in ixonEnv.consts do
let some c := lc.get? | continue
let blk? := match c.info with
| .iPrj p => some p.block
| .cPrj p => some p.block
| .rPrj p => some p.block
| .dPrj p => some p.block
| _ => none
if blk? == some addr then
let nm := match ixonEnv.getName? caddr with
| some n => toString (ixNameToLeanName n)
| none => s!"<unnamed {caddr}>"
IO.println nm
found := found + 1
if found == 0 then
IO.eprintln s!"error: no name or projection found for {addr}"
return 1
return 0

def runNameOfCmd (p : Cli.Parsed) : IO UInt32 := do
-- Suppress Rust-side `[compile_env]` scheduler noise; the only
-- signal this command emits is the name list on stdout.
Std.Internal.UV.System.osSetenv "IX_QUIET" "1"
let some addrArg := p.positionalArg? "addr"
| p.printError "error: must specify a 64-char hex address"; return 1
let argStr := addrArg.as! String
let some addr := Address.fromString argStr
| IO.eprintln s!"error: `{argStr}` is not a 64-char hex address"
return 1
let some path := (p.flag? "ixe").map (·.as! String)
| IO.eprintln "error: name-of requires --ixe <path>"
return 1
let bytes ← IO.FS.readBinFile path
let ixonEnv ← match Ixon.deEnvAnon bytes with
| .error e =>
IO.eprintln s!"error: failed to deserialize {path}: {e}"; return 1
| .ok env => pure env
nameLookup ixonEnv addr

end Ix.Cli.NameOfCmd

open Ix.Cli.NameOfCmd in
def nameOfCmd : Cli.Cmd := `[Cli|
"name-of" VIA runNameOfCmd;
"Resolve a content address back to its Lean name(s) in a `.ixe` env (may print several: structurally equivalent constants share an address)"

FLAGS:
"ixe" : String; "Path to a serialized `.ixe` env to resolve the address in (required)."

ARGS:
addr : String; "64-char hex content address to resolve. Prints every Lean.Name registered for it, one per line; for unnamed Muts blocks, prints the names of projection constants into the block instead."
]

end
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
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
33 changes: 0 additions & 33 deletions Check.lean

This file was deleted.

19 changes: 16 additions & 3 deletions Ix/Aiur/Stages/Codegen.lean
Original file line numberDiff line numberDiff line change
Expand Up@@ -635,8 +635,21 @@ private def emitUncBigUintDivMod (out : Nat) (a b : ValIdx) : Array RustStmt :=
declVal (out + 1) (.field (.var "__bu_qr") "1")
]

/-- `Op::Debug`: 0 outputs; println side effect. Skipped for now. -/
private def emitDebug : Array RustStmt := #[]
/-- `Op::Debug`: 0 outputs; println side effect, mirroring the bytecode
interpreter's `Op::Debug` arm (crates/aiur/src/execute.rs). Production
kernels contain no `dbg!`, so this emits nothing there; when probing
with `dbg!` it makes the (much faster) codegen kernel print the same
lines as `--interp bytecode`. -/
private def emitDebug (label : String) (args : Option (Array ValIdx)) : Array RustStmt :=
-- Escape the label for use inside a Rust format-string literal.
let esc := label.replace "\\" "\\\\" |>.replace "\"" "\\\""
|>.replace "{" "{{" |>.replace "}" "}}"
match args with
| none => #[.exprStmt (.lit s!"println!(\"{esc}\")")]
| some idxs =>
let holes := String.intercalate ", " (idxs.map (fun _ => "{}")).toList
let vals := String.intercalate ", " (idxs.map (s!"__v_{·}")).toList
#[.exprStmt (.lit s!"println!(\"{esc}: {holes}\", {vals})")]

/-- Top-level op dispatch. `out` = the first ValIdx for outputs;
callers must advance their counter by `Op.outputCount`. -/
Expand DownExpand Up@@ -670,7 +683,7 @@ def emitOp (out : Nat) (op : Op) : Array RustStmt :=
| .u32LessThan a b => emitU32LessThan out a b
| .u8RangeCheck i j => emitU8RangeCheck i j
| .unconstrainedBigUintDivMod a b => emitUncBigUintDivMod out a b
| .debug _ _ => emitDebug
| .debug label args => emitDebug label args

/-! ## Ctrl emission -/

Expand Down
2 changes: 1 addition & 1 deletion Ix/Cli/CheckCmd.lean
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/-
`ix check`: execute the IxVM Aiur kernel over a Lean or `.ixe`
environment, one constant at a time. Mirrors what `lake exe check` does.
environment, one constant at a time.
The Rust kernel typechecker that used to live under this name is now `ix check-rs`.

Usage shape:
Expand Down
98 changes: 98 additions & 0 deletions Ix/Cli/NameOfCmd.lean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
/-
`ix name-of <64-hex-addr> --ixe <path>`: resolve a content address
back to its Lean name(s) in an on-disk env.

A single address can carry MANY names: structurally equivalent
constants collapse to the same content address, and every such name
is registered against it in the env's `named` table. All of them are
printed, one per line.

If the address is not directly named (e.g. an anonymized Muts
block), scan the env for projection constants whose block field
points at it and print those projections' names — any of them
fast-repros the block via `ix check --ixe <path> <name>`.
-/
module
public import Cli
public import Std.Internal.UV.System
public import Ix.Address
public import Ix.Common
public import Ix.Environment
public import Ix.Ixon
public import Ix.Meta
public import Ix.Cli.NameResolve

public section

open Ix.Cli.NameResolve

namespace Ix.Cli.NameOfCmd

/-- Address → name(s). Direct hits come from filtering the env's
`named` table (the `addrToName` reverse index keeps only one name
per address, so it would silently drop structurally-equivalent
aliases); the projection scan is the fallback for unnamed blocks. -/
def nameLookup (ixonEnv : Ixon.Env) (addr : Address) : IO UInt32 := do
let mut found := 0
for (n, named) in ixonEnv.named do
if named.addr == addr then
IO.println (toString (ixNameToLeanName n))
found := found + 1
if found > 0 then
return 0
IO.eprintln s!"{addr} is not a named constant; \
scanning for projections into it..."
for (caddr, lc) in ixonEnv.consts do
let some c := lc.get? | continue
let blk? := match c.info with
| .iPrj p => some p.block
| .cPrj p => some p.block
| .rPrj p => some p.block
| .dPrj p => some p.block
| _ => none
if blk? == some addr then
let nm := match ixonEnv.getName? caddr with
| some n => toString (ixNameToLeanName n)
| none => s!"<unnamed {caddr}>"
IO.println nm
found := found + 1
if found == 0 then
IO.eprintln s!"error: no name or projection found for {addr}"
return 1
return 0

def runNameOfCmd (p : Cli.Parsed) : IO UInt32 := do
-- Suppress Rust-side `[compile_env]` scheduler noise; the only
-- signal this command emits is the name list on stdout.
Std.Internal.UV.System.osSetenv "IX_QUIET" "1"
let some addrArg := p.positionalArg? "addr"
| p.printError "error: must specify a 64-char hex address"; return 1
let argStr := addrArg.as! String
let some addr := Address.fromString argStr
| IO.eprintln s!"error: `{argStr}` is not a 64-char hex address"
return 1
let some path := (p.flag? "ixe").map (·.as! String)
| IO.eprintln "error: name-of requires --ixe <path>"
return 1
let bytes ← IO.FS.readBinFile path
let ixonEnv ← match Ixon.deEnvAnon bytes with
| .error e =>
IO.eprintln s!"error: failed to deserialize {path}: {e}"; return 1
| .ok env => pure env
nameLookup ixonEnv addr

end Ix.Cli.NameOfCmd

open Ix.Cli.NameOfCmd in
def nameOfCmd : Cli.Cmd := `[Cli|
"name-of" VIA runNameOfCmd;
"Resolve a content address back to its Lean name(s) in a `.ixe` env (may print several: structurally equivalent constants share an address)"

FLAGS:
"ixe" : String; "Path to a serialized `.ixe` env to resolve the address in (required)."

ARGS:
addr : String; "64-char hex content address to resolve. Prints every Lean.Name registered for it, one per line; for unnamed Muts blocks, prints the names of projection constants into the block instead."
]

end
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
33 changes: 0 additions & 33 deletions Check.lean

This file was deleted.

19 changes: 16 additions & 3 deletions Ix/Aiur/Stages/Codegen.lean
Original file line numberDiff line numberDiff line change
Expand Up@@ -635,8 +635,21 @@ private def emitUncBigUintDivMod (out : Nat) (a b : ValIdx) : Array RustStmt :=
declVal (out + 1) (.field (.var "__bu_qr") "1")
]

/-- `Op::Debug`: 0 outputs; println side effect. Skipped for now. -/
private def emitDebug : Array RustStmt := #[]
/-- `Op::Debug`: 0 outputs; println side effect, mirroring the bytecode
interpreter's `Op::Debug` arm (crates/aiur/src/execute.rs). Production
kernels contain no `dbg!`, so this emits nothing there; when probing
with `dbg!` it makes the (much faster) codegen kernel print the same
lines as `--interp bytecode`. -/
private def emitDebug (label : String) (args : Option (Array ValIdx)) : Array RustStmt :=
-- Escape the label for use inside a Rust format-string literal.
let esc := label.replace "\\" "\\\\" |>.replace "\"" "\\\""
|>.replace "{" "{{" |>.replace "}" "}}"
match args with
| none => #[.exprStmt (.lit s!"println!(\"{esc}\")")]
| some idxs =>
let holes := String.intercalate ", " (idxs.map (fun _ => "{}")).toList
let vals := String.intercalate ", " (idxs.map (s!"__v_{·}")).toList
#[.exprStmt (.lit s!"println!(\"{esc}: {holes}\", {vals})")]

/-- Top-level op dispatch. `out` = the first ValIdx for outputs;
callers must advance their counter by `Op.outputCount`. -/
Expand DownExpand Up@@ -670,7 +683,7 @@ def emitOp (out : Nat) (op : Op) : Array RustStmt :=
| .u32LessThan a b => emitU32LessThan out a b
| .u8RangeCheck i j => emitU8RangeCheck i j
| .unconstrainedBigUintDivMod a b => emitUncBigUintDivMod out a b
| .debug _ _ => emitDebug
| .debug label args => emitDebug label args

/-! ## Ctrl emission -/

Expand Down
2 changes: 1 addition & 1 deletion Ix/Cli/CheckCmd.lean
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/-
`ix check`: execute the IxVM Aiur kernel over a Lean or `.ixe`
environment, one constant at a time. Mirrors what `lake exe check` does.
environment, one constant at a time.
The Rust kernel typechecker that used to live under this name is now `ix check-rs`.

Usage shape:
Expand Down
98 changes: 98 additions & 0 deletions Ix/Cli/NameOfCmd.lean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
/-
`ix name-of <64-hex-addr> --ixe <path>`: resolve a content address
back to its Lean name(s) in an on-disk env.

A single address can carry MANY names: structurally equivalent
constants collapse to the same content address, and every such name
is registered against it in the env's `named` table. All of them are
printed, one per line.

If the address is not directly named (e.g. an anonymized Muts
block), scan the env for projection constants whose block field
points at it and print those projections' names — any of them
fast-repros the block via `ix check --ixe <path> <name>`.
-/
module
public import Cli
public import Std.Internal.UV.System
public import Ix.Address
public import Ix.Common
public import Ix.Environment
public import Ix.Ixon
public import Ix.Meta
public import Ix.Cli.NameResolve

public section

open Ix.Cli.NameResolve

namespace Ix.Cli.NameOfCmd

/-- Address → name(s). Direct hits come from filtering the env's
`named` table (the `addrToName` reverse index keeps only one name
per address, so it would silently drop structurally-equivalent
aliases); the projection scan is the fallback for unnamed blocks. -/
def nameLookup (ixonEnv : Ixon.Env) (addr : Address) : IO UInt32 := do
let mut found := 0
for (n, named) in ixonEnv.named do
if named.addr == addr then
IO.println (toString (ixNameToLeanName n))
found := found + 1
if found > 0 then
return 0
IO.eprintln s!"{addr} is not a named constant; \
scanning for projections into it..."
for (caddr, lc) in ixonEnv.consts do
let some c := lc.get? | continue
let blk? := match c.info with
| .iPrj p => some p.block
| .cPrj p => some p.block
| .rPrj p => some p.block
| .dPrj p => some p.block
| _ => none
if blk? == some addr then
let nm := match ixonEnv.getName? caddr with
| some n => toString (ixNameToLeanName n)
| none => s!"<unnamed {caddr}>"
IO.println nm
found := found + 1
if found == 0 then
IO.eprintln s!"error: no name or projection found for {addr}"
return 1
return 0

def runNameOfCmd (p : Cli.Parsed) : IO UInt32 := do
-- Suppress Rust-side `[compile_env]` scheduler noise; the only
-- signal this command emits is the name list on stdout.
Std.Internal.UV.System.osSetenv "IX_QUIET" "1"
let some addrArg := p.positionalArg? "addr"
| p.printError "error: must specify a 64-char hex address"; return 1
let argStr := addrArg.as! String
let some addr := Address.fromString argStr
| IO.eprintln s!"error: `{argStr}` is not a 64-char hex address"
return 1
let some path := (p.flag? "ixe").map (·.as! String)
| IO.eprintln "error: name-of requires --ixe <path>"
return 1
let bytes ← IO.FS.readBinFile path
let ixonEnv ← match Ixon.deEnvAnon bytes with
| .error e =>
IO.eprintln s!"error: failed to deserialize {path}: {e}"; return 1
| .ok env => pure env
nameLookup ixonEnv addr

end Ix.Cli.NameOfCmd

open Ix.Cli.NameOfCmd in
def nameOfCmd : Cli.Cmd := `[Cli|
"name-of" VIA runNameOfCmd;
"Resolve a content address back to its Lean name(s) in a `.ixe` env (may print several: structurally equivalent constants share an address)"

FLAGS:
"ixe" : String; "Path to a serialized `.ixe` env to resolve the address in (required)."

ARGS:
addr : String; "64-char hex content address to resolve. Prints every Lean.Name registered for it, one per line; for unnamed Muts blocks, prints the names of projection constants into the block instead."
]

end
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
33 changes: 0 additions & 33 deletions Check.lean

This file was deleted.

19 changes: 16 additions & 3 deletions Ix/Aiur/Stages/Codegen.lean
Original file line numberDiff line numberDiff line change
Expand Up@@ -635,8 +635,21 @@ private def emitUncBigUintDivMod (out : Nat) (a b : ValIdx) : Array RustStmt :=
declVal (out + 1) (.field (.var "__bu_qr") "1")
]

/-- `Op::Debug`: 0 outputs; println side effect. Skipped for now. -/
private def emitDebug : Array RustStmt := #[]
/-- `Op::Debug`: 0 outputs; println side effect, mirroring the bytecode
interpreter's `Op::Debug` arm (crates/aiur/src/execute.rs). Production
kernels contain no `dbg!`, so this emits nothing there; when probing
with `dbg!` it makes the (much faster) codegen kernel print the same
lines as `--interp bytecode`. -/
private def emitDebug (label : String) (args : Option (Array ValIdx)) : Array RustStmt :=
-- Escape the label for use inside a Rust format-string literal.
let esc := label.replace "\\" "\\\\" |>.replace "\"" "\\\""
|>.replace "{" "{{" |>.replace "}" "}}"
match args with
| none => #[.exprStmt (.lit s!"println!(\"{esc}\")")]
| some idxs =>
let holes := String.intercalate ", " (idxs.map (fun _ => "{}")).toList
let vals := String.intercalate ", " (idxs.map (s!"__v_{·}")).toList
#[.exprStmt (.lit s!"println!(\"{esc}: {holes}\", {vals})")]

/-- Top-level op dispatch. `out` = the first ValIdx for outputs;
callers must advance their counter by `Op.outputCount`. -/
Expand DownExpand Up@@ -670,7 +683,7 @@ def emitOp (out : Nat) (op : Op) : Array RustStmt :=
| .u32LessThan a b => emitU32LessThan out a b
| .u8RangeCheck i j => emitU8RangeCheck i j
| .unconstrainedBigUintDivMod a b => emitUncBigUintDivMod out a b
| .debug _ _ => emitDebug
| .debug label args => emitDebug label args

/-! ## Ctrl emission -/

Expand Down
2 changes: 1 addition & 1 deletion Ix/Cli/CheckCmd.lean
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/-
`ix check`: execute the IxVM Aiur kernel over a Lean or `.ixe`
environment, one constant at a time. Mirrors what `lake exe check` does.
environment, one constant at a time.
The Rust kernel typechecker that used to live under this name is now `ix check-rs`.

Usage shape:
Expand Down
98 changes: 98 additions & 0 deletions Ix/Cli/NameOfCmd.lean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
/-
`ix name-of <64-hex-addr> --ixe <path>`: resolve a content address
back to its Lean name(s) in an on-disk env.

A single address can carry MANY names: structurally equivalent
constants collapse to the same content address, and every such name
is registered against it in the env's `named` table. All of them are
printed, one per line.

If the address is not directly named (e.g. an anonymized Muts
block), scan the env for projection constants whose block field
points at it and print those projections' names — any of them
fast-repros the block via `ix check --ixe <path> <name>`.
-/
module
public import Cli
public import Std.Internal.UV.System
public import Ix.Address
public import Ix.Common
public import Ix.Environment
public import Ix.Ixon
public import Ix.Meta
public import Ix.Cli.NameResolve

public section

open Ix.Cli.NameResolve

namespace Ix.Cli.NameOfCmd

/-- Address → name(s). Direct hits come from filtering the env's
`named` table (the `addrToName` reverse index keeps only one name
per address, so it would silently drop structurally-equivalent
aliases); the projection scan is the fallback for unnamed blocks. -/
def nameLookup (ixonEnv : Ixon.Env) (addr : Address) : IO UInt32 := do
let mut found := 0
for (n, named) in ixonEnv.named do
if named.addr == addr then
IO.println (toString (ixNameToLeanName n))
found := found + 1
if found > 0 then
return 0
IO.eprintln s!"{addr} is not a named constant; \
scanning for projections into it..."
for (caddr, lc) in ixonEnv.consts do
let some c := lc.get? | continue
let blk? := match c.info with
| .iPrj p => some p.block
| .cPrj p => some p.block
| .rPrj p => some p.block
| .dPrj p => some p.block
| _ => none
if blk? == some addr then
let nm := match ixonEnv.getName? caddr with
| some n => toString (ixNameToLeanName n)
| none => s!"<unnamed {caddr}>"
IO.println nm
found := found + 1
if found == 0 then
IO.eprintln s!"error: no name or projection found for {addr}"
return 1
return 0

def runNameOfCmd (p : Cli.Parsed) : IO UInt32 := do
-- Suppress Rust-side `[compile_env]` scheduler noise; the only
-- signal this command emits is the name list on stdout.
Std.Internal.UV.System.osSetenv "IX_QUIET" "1"
let some addrArg := p.positionalArg? "addr"
| p.printError "error: must specify a 64-char hex address"; return 1
let argStr := addrArg.as! String
let some addr := Address.fromString argStr
| IO.eprintln s!"error: `{argStr}` is not a 64-char hex address"
return 1
let some path := (p.flag? "ixe").map (·.as! String)
| IO.eprintln "error: name-of requires --ixe <path>"
return 1
let bytes ← IO.FS.readBinFile path
let ixonEnv ← match Ixon.deEnvAnon bytes with
| .error e =>
IO.eprintln s!"error: failed to deserialize {path}: {e}"; return 1
| .ok env => pure env
nameLookup ixonEnv addr

end Ix.Cli.NameOfCmd

open Ix.Cli.NameOfCmd in
def nameOfCmd : Cli.Cmd := `[Cli|
"name-of" VIA runNameOfCmd;
"Resolve a content address back to its Lean name(s) in a `.ixe` env (may print several: structurally equivalent constants share an address)"

FLAGS:
"ixe" : String; "Path to a serialized `.ixe` env to resolve the address in (required)."

ARGS:
addr : String; "64-char hex content address to resolve. Prints every Lean.Name registered for it, one per line; for unnamed Muts blocks, prints the names of projection constants into the block instead."
]

end
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
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
33 changes: 0 additions & 33 deletions Check.lean

This file was deleted.

19 changes: 16 additions & 3 deletions Ix/Aiur/Stages/Codegen.lean
Original file line numberDiff line numberDiff line change
Expand Up@@ -635,8 +635,21 @@ private def emitUncBigUintDivMod (out : Nat) (a b : ValIdx) : Array RustStmt :=
declVal (out + 1) (.field (.var "__bu_qr") "1")
]

/-- `Op::Debug`: 0 outputs; println side effect. Skipped for now. -/
private def emitDebug : Array RustStmt := #[]
/-- `Op::Debug`: 0 outputs; println side effect, mirroring the bytecode
interpreter's `Op::Debug` arm (crates/aiur/src/execute.rs). Production
kernels contain no `dbg!`, so this emits nothing there; when probing
with `dbg!` it makes the (much faster) codegen kernel print the same
lines as `--interp bytecode`. -/
private def emitDebug (label : String) (args : Option (Array ValIdx)) : Array RustStmt :=
-- Escape the label for use inside a Rust format-string literal.
let esc := label.replace "\\" "\\\\" |>.replace "\"" "\\\""
|>.replace "{" "{{" |>.replace "}" "}}"
match args with
| none => #[.exprStmt (.lit s!"println!(\"{esc}\")")]
| some idxs =>
let holes := String.intercalate ", " (idxs.map (fun _ => "{}")).toList
let vals := String.intercalate ", " (idxs.map (s!"__v_{·}")).toList
#[.exprStmt (.lit s!"println!(\"{esc}: {holes}\", {vals})")]

/-- Top-level op dispatch. `out` = the first ValIdx for outputs;
callers must advance their counter by `Op.outputCount`. -/
Expand DownExpand Up@@ -670,7 +683,7 @@ def emitOp (out : Nat) (op : Op) : Array RustStmt :=
| .u32LessThan a b => emitU32LessThan out a b
| .u8RangeCheck i j => emitU8RangeCheck i j
| .unconstrainedBigUintDivMod a b => emitUncBigUintDivMod out a b
| .debug _ _ => emitDebug
| .debug label args => emitDebug label args

/-! ## Ctrl emission -/

Expand Down
2 changes: 1 addition & 1 deletion Ix/Cli/CheckCmd.lean
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
/-
`ix check`: execute the IxVM Aiur kernel over a Lean or `.ixe`
environment, one constant at a time. Mirrors what `lake exe check` does.
environment, one constant at a time.
The Rust kernel typechecker that used to live under this name is now `ix check-rs`.

Usage shape:
Expand Down
98 changes: 98 additions & 0 deletions Ix/Cli/NameOfCmd.lean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
/-
`ix name-of <64-hex-addr> --ixe <path>`: resolve a content address
back to its Lean name(s) in an on-disk env.

A single address can carry MANY names: structurally equivalent
constants collapse to the same content address, and every such name
is registered against it in the env's `named` table. All of them are
printed, one per line.

If the address is not directly named (e.g. an anonymized Muts
block), scan the env for projection constants whose block field
points at it and print those projections' names — any of them
fast-repros the block via `ix check --ixe <path> <name>`.
-/
module
public import Cli
public import Std.Internal.UV.System
public import Ix.Address
public import Ix.Common
public import Ix.Environment
public import Ix.Ixon
public import Ix.Meta
public import Ix.Cli.NameResolve

public section

open Ix.Cli.NameResolve

namespace Ix.Cli.NameOfCmd

/-- Address → name(s). Direct hits come from filtering the env's
`named` table (the `addrToName` reverse index keeps only one name
per address, so it would silently drop structurally-equivalent
aliases); the projection scan is the fallback for unnamed blocks. -/
def nameLookup (ixonEnv : Ixon.Env) (addr : Address) : IO UInt32 := do
let mut found := 0
for (n, named) in ixonEnv.named do
if named.addr == addr then
IO.println (toString (ixNameToLeanName n))
found := found + 1
if found > 0 then
return 0
IO.eprintln s!"{addr} is not a named constant; \
scanning for projections into it..."
for (caddr, lc) in ixonEnv.consts do
let some c := lc.get? | continue
let blk? := match c.info with
| .iPrj p => some p.block
| .cPrj p => some p.block
| .rPrj p => some p.block
| .dPrj p => some p.block
| _ => none
if blk? == some addr then
let nm := match ixonEnv.getName? caddr with
| some n => toString (ixNameToLeanName n)
| none => s!"<unnamed {caddr}>"
IO.println nm
found := found + 1
if found == 0 then
IO.eprintln s!"error: no name or projection found for {addr}"
return 1
return 0

def runNameOfCmd (p : Cli.Parsed) : IO UInt32 := do
-- Suppress Rust-side `[compile_env]` scheduler noise; the only
-- signal this command emits is the name list on stdout.
Std.Internal.UV.System.osSetenv "IX_QUIET" "1"
let some addrArg := p.positionalArg? "addr"
| p.printError "error: must specify a 64-char hex address"; return 1
let argStr := addrArg.as! String
let some addr := Address.fromString argStr
| IO.eprintln s!"error: `{argStr}` is not a 64-char hex address"
return 1
let some path := (p.flag? "ixe").map (·.as! String)
| IO.eprintln "error: name-of requires --ixe <path>"
return 1
let bytes ← IO.FS.readBinFile path
let ixonEnv ← match Ixon.deEnvAnon bytes with
| .error e =>
IO.eprintln s!"error: failed to deserialize {path}: {e}"; return 1
| .ok env => pure env
nameLookup ixonEnv addr

end Ix.Cli.NameOfCmd

open Ix.Cli.NameOfCmd in
def nameOfCmd : Cli.Cmd := `[Cli|
"name-of" VIA runNameOfCmd;
"Resolve a content address back to its Lean name(s) in a `.ixe` env (may print several: structurally equivalent constants share an address)"

FLAGS:
"ixe" : String; "Path to a serialized `.ixe` env to resolve the address in (required)."

ARGS:
addr : String; "64-char hex content address to resolve. Prints every Lean.Name registered for it, one per line; for unnamed Muts blocks, prints the names of projection constants into the block instead."
]

end
Loading
Loading