[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Debug variables and VIEW



Hi,

I have a spec (cut-down version below) where I need to add a debug variable (cmd) to keep track of how an invariant fails. As expected, such variable increases the state space significantly while not having any other effect on the actual model. So I added a VIEW statement to the .cfg file so that 'cmd' is left out. While it indeed decreases the state space, it still doesn't go all the way to the no debug variable case.

TLC2 Version 2.13 of 18 July 2018

Without the 'cmd' debug variable (or cmd only set to inst[1] in the spec below, which is part of the symmetry optimisation):

5369 states generated, 244 distinct states found

With the debug variable and VIEW set to cpu_vars:

10341 states generated, 470 distinct states found

With the debug variable and default view:

32935 states generated, 1497 distinct states found

Is there anything I miss? Please note that I run TLC on the command line (I couldn't find an ARM build of the Toolbox ;)).

Thank you,

Catalin

-------------------------- MODULE CPU ----------------------------------------
EXTENDS
Sequences, TLC

CONSTANTS REGS
,  \* the set of CPU registers (e.g. {r1, r2})
          ADDRS
, \* the set of memory addresses (e.g. {a1, a2})
          DATA  
\* the set of primitive data values (e.g. {d1, d2})

\* Zero data value (other than ADDRS or DATA)
Zero == CHOOSE val : val \notin ADDRS \cup DATA

\* TLC symmetry optimisations
Perms ==
 
Permutations(REGS) \cup Permutations(ADDRS) \cup Permutations(DATA)

VARIABLES regs
, \* CPU registers
  mem
,          \* memory (virtual)
  exception
,    \* exception status
  cmd          
\* last executed command (debug)

cpu_vars
== << regs, mem, exception >>

(* A memory location can store ADDRS or DATA or Zero *)
VALUES
== ADDRS \cup DATA \cup {Zero}

CPUTypeOK ==
 
/\ regs \in [REGS -> VALUES]
  /
\ mem \in [ADDRS -> VALUES]
 
/\ exception \in BOOLEAN

(* Registers and memory are initialised to Zero *)
CPUInit ==
 
/\ regs = [r \in REGS |-> Zero]
  /
\ mem = [a \in ADDRS |-> Zero]
 
/\ exception = FALSE
 
/\ cmd = << >>

(* Executable CPU instructions *)

(* Move an immediate value to a register *)
MOVI
(reg, imm) ==
 
/\ regs' = [regs EXCEPT ![reg] = imm]
  /
\ UNCHANGED << mem, exception >>

(* Move the value of a register to another *)
MOV
(regt, regm) ==
 
/\ regs' = [regs EXCEPT ![regt] = regs[regm]]
  /
\ UNCHANGED << mem, exception >>

(* Load a value from memory at the address specified by regm into
   regt
. If the access is not permitted (invalid pointer), set the
   exception state
*)
LDR
(regt, regm) ==
 
/\ LET pointer == regs[regm]
     IN  IF pointer \in ADDRS
         THEN /
\ regs' = [regs EXCEPT ![regt] = mem[pointer]]
              /\ UNCHANGED exception
         ELSE /\ exception'
= TRUE
             
/\ UNCHANGED regs
 
/\ UNCHANGED mem

(* Store the value in regt to memory at the address specified by
   regm
. If the access is not permitted (invalid pointer), set the
   exception state
*)
STR
(regt, regm) ==
 
/\ LET pointer == regs[regm]
     IN  IF pointer \in ADDRS
         THEN /
\ mem' = [mem EXCEPT ![pointer] = regs[regt]]
              /\ UNCHANGED exception
         ELSE /\ exception'
= TRUE
             
/\ UNCHANGED mem
 
/\ UNCHANGED regs

(* Execute an instruction in the form << "name", arg1, arg2 >> *)
CPUExec(inst) ==
 
/\ CASE inst[1] = "movi" -> MOVI(inst[2], inst[3])
       [] inst[1] = "mov"  -> MOV(inst[2], inst[3])
       [] inst[1] = "ldr"  -> LDR(inst[2], inst[3])
       [] inst[1] = "str"  -> STR(inst[2], inst[3])
       [] OTHER -> Assert(FALSE, << "Unknown instruction", inst[1] >>)
  /
\ cmd' = inst

------------------------------------------------------------------------------
CPUNext ==
  \/ \E reg \in REGS, imm \in VALUES : CPUExec(<< "movi", reg, imm >>)
  \/ \E regt, regm \in REGS : CPUExec(<< "mov", regt, regm >>)
  \/ \E regt, regm \in REGS : CPUExec(<< "ldr", regt, regm >>)
  \/ \E regt, regm \in REGS : CPUExec(<< "str", regt, regm >>)

CPUSpec == CPUInit /\ [][CPUNext]_<< cpu_vars, cmd >>

THEOREM CPUSpec => []CPUTypeOK
==============================================================================

\* CPU.cfg
CONSTANTS REGS = {r1, r2}
          ADDRS = {a1, a2}
          DATA = "" d2}
          Zero = Zero

SYMMETRY Perms

VIEW cpu_vars

SPECIFICATION CPUSpec

INVARIANTS CPUTypeOK