Skip to content

Commit 30d54ed

Browse files
committed
Another go at a good definition for the semantics
* This now allows reasoning about the n'th frame from an arbitrary state and has a load of syntax to make it prettier
1 parent a70d3ee commit 30d54ed

4 files changed

Lines changed: 561 additions & 471 deletions

File tree

Valaig/Aig/Basic.lean

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ def getVar (idx : InputIdx) (aig : Aig) (valid : idx.validIn aig := by grind) :
364364

365365
@[always_inline, simp]
366366
abbrev getLit (idx : InputIdx) (aig : Aig) (valid : idx.validIn aig := by grind) : Lit :=
367-
idx.getVar aig valid
367+
idx.getVar aig valid |>.toLit
368368

369369
end InputIdx
370370

@@ -399,7 +399,7 @@ def getVar (idx : LatchIdx) (aig : Aig) (valid : idx.validIn aig := by grind) :
399399

400400
@[always_inline, simp]
401401
abbrev getLit (idx : LatchIdx) (aig : Aig) (valid : idx.validIn aig := by grind) : Lit :=
402-
idx.getVar aig valid
402+
idx.getVar aig valid |>.toLit
403403

404404
@[always_inline]
405405
def getNext (idx : LatchIdx) (aig : Aig) (valid : idx.validIn aig := by grind) : Lit :=
@@ -545,7 +545,7 @@ theorem getVar_latch {idx : LatchIdx} (valid : (latch idx).validIn aig) :
545545

546546
@[always_inline, expose, simp, grind unfold]
547547
def getLit (idx : LeafIdx) (aig : Aig) (valid : idx.validIn aig := by grind) : Lit :=
548-
idx.getVar aig valid
548+
idx.getVar aig valid |>.toLit
549549

550550
end LeafIdx
551551

Valaig/Aig/Projections.lean

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -156,22 +156,21 @@ namespace resetAig
156156

157157
variable {state : Aig} {map : Array Lit} {swf : state.WellFormed}
158158
variable {denote : ∀ {assign} {var : Var} (lt : var.idx < map.size),
159-
state.denoteComb map[var.idx] assign = aig.denoteResetVar var assign}
160-
variable {assign : LeafIdx -> Bool}
159+
⟦state, map[var.idx], assign⟧c0 = ⟦aig, var, assign⟧sv0}
160+
variable {assign : LeafIdx -> Frame -> Bool}
161+
include denote
161162

162-
include denote in
163163
theorem denote_mapTo (lit : Lit) {lt : lit.var.idx < map.size} :
164-
state.denoteComb (lit.mapTo map[lit.var.idx]) assign swf = aig.denoteReset lit assign wf := by
165-
grind [denoteReset_eq_denoteResetVar]
164+
state, lit.mapTo map[lit.var.idx], assign⟧c0 = ⟦aig, lit, assign⟧s0 := by
165+
grind
166166

167-
include denote in
168167
@[local grind =]
169168
theorem denote_step {var var' a b c}
170169
{inputInvalid : ∀ {idx}, aig[var'] = .input idx → ¬idx.validIn state}
171170
{latchInvalid : ∀ {idx}, aig[var'] = .latch idx → ¬idx.validIn state} :
172171
let res := resetAig.step aig state map var' a wf b c
173172
(lt : var.idx < res.snd.size) →
174-
res.fst.denoteComb res.snd[var.idx] assign = aig.denoteResetVar var assign := by
173+
res.fst, res.snd[var.idx], assign⟧c0 = aig, var, assign⟧sv0 := by
175174
intro res h
176175
rw [show res.snd[var.idx] = (map.push res.snd[map.size])[var.idx] by simp [res, resetAig.step], Array.getElem_push]
177176
split
@@ -185,10 +184,9 @@ theorem denote_step {var var' a b c}
185184
· grind -splitIte [denote_mapTo (aig := aig)]
186185
· grind -splitMatch -splitIte [denote_mapTo (aig := aig)]
187186

188-
include denote in
189187
theorem denote_go (lit : Lit.In aig) {it a b c d wf'} :
190188
let res := resetAig.go aig wf it state map swf a b c d
191-
res.fst.denoteComb (res.snd lit) assign wf' = aig.denoteReset lit assign := by
189+
res.fst.denoteC (res.snd lit) assign 0 wf' = aig, lit, assign⟧s0 := by
192190
fun_induction resetAig.go
193191
· grind only [denote_mapTo]
194192
next ih =>
@@ -200,8 +198,7 @@ end resetAig
200198

201199
@[simp, grind =]
202200
theorem denote_resetAig {assign} {lit : Lit.In aig} :
203-
aig.resetAig.fst.denoteComb (aig.resetAig.snd lit) assign =
204-
aig.denoteReset lit assign wf := by
201+
⟦aig.resetAig.fst, aig.resetAig.snd lit, assign⟧c0 = ⟦aig, lit, assign⟧s0 := by
205202
grind [resetAig, resetAig.denote_go]
206203

207204
namespace transAig

Valaig/Aig/Refs.lean

Lines changed: 88 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,21 @@ Returns the constant literal of specified value.
225225
def constant (value : Bool) : Lit :=
226226
.ofIdx value.toNat
227227

228-
@[simp, grind =]
228+
@[simp]
229229
theorem var_constant {value : Bool} :
230230
(constant value).var = .constant := by
231231
cases value <;> grind [constant]
232232

233-
@[simp, grind =]
233+
@[simp]
234234
theorem inverted_constant {value : Bool} :
235235
(constant value).inverted = value := by
236236
grind [constant]
237237

238+
@[grind =]
239+
theorem constant_eq {value : Bool} :
240+
(constant value) = .mk .constant value := by
241+
grind [var_constant, inverted_constant]
242+
238243
@[simp, grind =]
239244
theorem idx_constant {value : Bool} :
240245
(constant value).idx = value.toNat := by
@@ -248,11 +253,26 @@ To determine if a literal is false it suffices to check for equality with this.
248253
def false : Lit :=
249254
.ofIdx 0
250255

251-
@[simp, grind =]
256+
@[simp, grind =]
252257
theorem false_eq :
253258
false = constant .false := by
254259
simp [constant, false]
255260

261+
@[simp]
262+
theorem var_false :
263+
false.var = .constant := by
264+
grind
265+
266+
@[simp]
267+
theorem inverted_false :
268+
¬false.inverted := by
269+
grind
270+
271+
@[simp]
272+
theorem idx_false :
273+
false.idx = 0 := by
274+
grind
275+
256276
/--
257277
The (single) true literal.
258278
To determine if a literal is true it suffices to check for equality with this.
@@ -261,11 +281,26 @@ To determine if a literal is true it suffices to check for equality with this.
261281
def true : Lit :=
262282
.ofIdx 1
263283

264-
@[simp, grind =]
284+
@[simp, grind =]
265285
theorem true_eq :
266286
true = constant .true := by
267287
simp [constant, true]
268288

289+
@[simp]
290+
theorem var_true :
291+
true.var = .constant := by
292+
grind
293+
294+
@[simp]
295+
theorem inverted_true :
296+
true.inverted := by
297+
grind
298+
299+
@[simp]
300+
theorem idx_true :
301+
true.idx = 1 := by
302+
grind
303+
269304
/--
270305
True iff the literal references a constant.
271306
-/
@@ -347,30 +382,32 @@ Optionally inverts the polarity of a literal.
347382
def invert (lit : Lit) (doInvert : Bool := .true) : Lit :=
348383
.ofIdx <| lit.idx ^^^ doInvert.toNat
349384

350-
@[simp, grind =]
385+
@[simp]
351386
theorem inverted_invert_false :
352387
(lit.invert .false).inverted = lit.inverted := by
353388
simp [invert]
354389

355-
@[simp, grind =]
390+
@[simp]
356391
theorem inverted_invert_true :
357392
(lit.invert .true).inverted = ¬lit.inverted := by
358393
simp [invert, inverted]
359394

395+
@[simp]
360396
theorem inverted_invert {doInvert : Bool} :
361397
(lit.invert doInvert).inverted = (doInvert ≠ lit.inverted) := by
362-
cases doInvert <;> grind
363-
364-
grind_pattern inverted_invert => (lit.invert doInvert).inverted where
365-
doInvert =/= Bool.false
366-
doInvert =/= Bool.true
398+
cases doInvert <;> simp
367399

368-
@[simp, grind =]
400+
@[simp]
369401
theorem var_invert {doInvert : Bool} :
370402
(lit.invert doInvert).var = lit.var := by
371403
simp only [invert, var, Nat.xor_div_two]
372404
cases doInvert <;> simp
373405

406+
@[grind =]
407+
theorem invert_eq {doInvert : Bool} :
408+
lit.invert doInvert = .mk lit.var (doInvert ^^ lit.inverted) := by
409+
grind [var_invert, inverted_invert]
410+
374411
/--
375412
Sets a literal's polarity to false.
376413
This implementation is more efficient than using `Lit.mk l.var false`.
@@ -380,16 +417,21 @@ def strip (lit : Lit) : Lit :=
380417
-- TODO(u32): Switch this to bit clearing
381418
.ofIdx <| lit.idx ^^^ (lit.idx &&& 1)
382419

383-
@[simp, grind =]
420+
@[simp]
384421
theorem var_strip :
385422
lit.strip.var = lit.var := by
386423
simp [strip, var, Nat.xor_div_two]
387424

388-
@[simp, grind .]
425+
@[simp]
389426
theorem inverted_strip :
390427
¬lit.strip.inverted := by
391428
simp [strip, inverted]
392429

430+
@[grind =]
431+
theorem strip_eq :
432+
lit.strip = .mk lit.var .false := by
433+
grind [var_strip, inverted_strip]
434+
393435
/--
394436
Maps the literal's variable to a new literal, before inverting the new literal if the
395437
original was also inverted.
@@ -398,49 +440,64 @@ original was also inverted.
398440
def mapTo (lit new : Lit) : Lit :=
399441
new.invert lit.inverted
400442

401-
@[simp, grind =]
443+
@[simp]
402444
theorem var_mapTo {new : Lit} :
403445
(lit.mapTo new).var = new.var := by
404446
simp [mapTo]
405447

406-
@[simp, grind =]
448+
@[simp]
407449
theorem inverted_mapTo {new : Lit} :
408450
(lit.mapTo new).inverted = (new.inverted ≠ lit.inverted) := by
409451
grind [mapTo]
410452

453+
@[grind =]
454+
theorem mapTo_eq {new : Lit} :
455+
lit.mapTo new = .mk new.var (new.inverted ≠ lit.inverted) := by
456+
grind [var_mapTo, inverted_mapTo]
457+
411458
/--
412459
Replaces the literal's variable to a literal with a new variable, keeping the inversion.
413460
-/
414461
@[inline]
415462
def mapToVar (lit : Lit) (var : Var) : Lit :=
416463
mk var lit.inverted
417464

418-
@[simp, grind =]
465+
@[simp]
419466
theorem var_mapToVar {var : Var} :
420467
(lit.mapToVar var).var = var := by
421468
simp [mapToVar]
422469

423-
@[simp, grind =]
470+
@[simp]
424471
theorem inverted_mapToVar {var : Var} :
425472
(lit.mapToVar var).inverted = lit.inverted := by
426473
simp [mapToVar]
427474

475+
@[grind =]
476+
theorem mapToVar_eq {var : Var} :
477+
lit.mapToVar var = .mk var lit.inverted := by
478+
grind [var_mapToVar, inverted_mapToVar]
479+
428480
@[inline]
429481
def ofFanin (fi : Std.Sat.AIG.Fanin) : Lit :=
430482
-- Currently Lit and Fanin use the same bit stuffing so we can losslessly
431483
-- convert between them
432484
.ofIdx fi.val
433485

434-
@[simp, grind =]
435-
theorem var_ofFanin (fi : Std.Sat.AIG.Fanin) :
486+
@[simp]
487+
theorem var_ofFanin {fi : Std.Sat.AIG.Fanin} :
436488
(ofFanin fi).var = .ofIdx fi.gate := by
437489
simp [ofFanin, Std.Sat.AIG.Fanin.gate, var]
438490

439-
@[simp, grind =]
440-
theorem inverted_ofFanin (fi : Std.Sat.AIG.Fanin) :
491+
@[simp]
492+
theorem inverted_ofFanin {fi : Std.Sat.AIG.Fanin} :
441493
(ofFanin fi).inverted = fi.invert := by
442494
simp [ofFanin, Std.Sat.AIG.Fanin.invert, inverted]
443495

496+
@[grind =]
497+
theorem ofFanin_eq {fi : Std.Sat.AIG.Fanin} :
498+
ofFanin fi = .mk (.ofIdx fi.gate) fi.invert := by
499+
grind [var_ofFanin, inverted_ofFanin]
500+
444501
@[inline]
445502
def toFanin (lit : Lit) : Std.Sat.AIG.Fanin :=
446503
.ofRaw lit.idx
@@ -474,16 +531,21 @@ variable {α} [DecidableEq α] [Hashable α] {aig : Std.Sat.AIG α}
474531
def ofRef (ref : aig.Ref) : Lit :=
475532
mk (.ofRef ref) ref.invert
476533

477-
@[simp, grind =]
534+
@[simp]
478535
theorem var_ofRef (ref : aig.Ref) :
479536
(ofRef ref).var = (.ofRef ref) := by
480537
simp [ofRef]
481538

482-
@[simp, grind =]
539+
@[simp]
483540
theorem inverted_ofRef (ref : aig.Ref) :
484541
(ofRef ref).inverted = ref.invert := by
485542
simp [ofRef]
486543

544+
@[simp, grind =]
545+
theorem ofRef_eq (ref : aig.Ref) :
546+
ofRef ref = .mk (.ofRef ref) ref.invert := by
547+
grind [var_ofRef, inverted_ofRef]
548+
487549
@[inline]
488550
def toRef (lit : Lit) (h : lit.var.idx < aig.decls.size) : aig.Ref :=
489551
.mk lit.var.idx lit.inverted h
@@ -512,39 +574,6 @@ end
512574

513575
end Lit
514576

515-
namespace Var
516-
variable {var : Var}
517-
518-
@[inline]
519-
def toLit (var : Var) (invert : Bool := false) : Lit :=
577+
@[inline, expose, reducible, simp, grind unfold]
578+
def Var.toLit (var : Var) (invert : Bool := false) : Lit :=
520579
.mk var invert
521-
522-
@[simp, grind =]
523-
theorem var_toLit {invert : Bool} :
524-
(var.toLit invert).var = var := by
525-
simp [toLit]
526-
527-
@[simp, grind =]
528-
theorem inverted_toLit {invert : Bool} :
529-
(var.toLit invert).inverted = invert := by
530-
simp [toLit]
531-
532-
@[inline]
533-
def toLit' (var : Var) : Lit :=
534-
var.toLit
535-
536-
@[always_inline]
537-
instance : Coe Var Lit where
538-
coe := Var.toLit'
539-
540-
@[simp, grind =]
541-
theorem var_toLit' :
542-
var.toLit'.var = var := by
543-
simp [toLit']
544-
545-
@[simp, grind =]
546-
theorem inverted_toLit' :
547-
var.toLit'.inverted = False := by
548-
simp [toLit']
549-
550-
end Var

0 commit comments

Comments
 (0)