From 36ff1f03fb47af3ebed45e7f319f9dce62dff292 Mon Sep 17 00:00:00 2001
From: Michael Leuschel <leuschel@cs.uni-duesseldorf.de>
Date: Tue, 11 Feb 2020 15:51:48 +0100
Subject: [PATCH] add debugging section

---
 .../user/12_BLanguage/22_Debugging.adoc       | 185 ++++++++++++++++++
 1 file changed, 185 insertions(+)
 create mode 100644 src/docs/chapter/user/12_BLanguage/22_Debugging.adoc

diff --git a/src/docs/chapter/user/12_BLanguage/22_Debugging.adoc b/src/docs/chapter/user/12_BLanguage/22_Debugging.adoc
new file mode 100644
index 0000000..3964007
--- /dev/null
+++ b/src/docs/chapter/user/12_BLanguage/22_Debugging.adoc
@@ -0,0 +1,185 @@
+
+[[debugging-prob]]
+= Debugging Models with ProB
+
+There are various ways in which you can debug your model.
+We focus here on debugging performance issues
+
+== Debugging with LibraryIO
+
+The [[External Functions|standard library]] "LibraryIO.def" contains various external functions and predicates with which you can instrument your formal model.
+
+To use the library in your model you need to include the following 
+
+....
+DEFINITIONS
+ "LibraryIO.def"
+....
+
+With the external predicate <tt>printf</tt> you can view values of variables and identifiers. The printf predicate is always true and will print its arguments when all of them have been fully computed.
+The printf predicate uses the format from SICStus Prolog for the format string.
+The most important are <tt>~w</tt> for printing an argument and <tt>~n</tt>
+for a newline. There must be exactly as many <tt>~w</tt> in the format string as there
+are aguments.
+Below is a small example, to inspect in which order ProB enumerates values.
+The example is typed in the REPL of  [[Using_the_Command-Line_Version_of_ProB|probcli]]
+(started using the command <tt>probcli -repl File.mch</tt> where <tt>File.mch</tt> includes the definitions section above):
+
+....
+>>> {x,y | x:1..5 & y:1..2 & x+y=6 & printf("x=~w~n",[x]) & printf("y=~w~n",[y])}
+y=1
+x=5
+y=2
+x=4
+Expression Value = 
+{(4|->2),(5|->1)}
+....
+
+As you can see, ProB has enumerated y before x, as its domain was smaller.
+
+You can use the external function <tt>observe</tt> to inspect a list of
+identifiers:
+
+....
+>>> {x,y | x:1..5 & y:1..2 & x+y=6 & observe((x,y))}
+ observing x
+ observing y
+ y = 1  (walltime: 562188 ms)
+. x = 5  (walltime: 562188 ms)
+..* Value complete: x |-> y = (5|->1)  (walltime: 562188 ms)
+------
+ y = 2  (walltime: 562188 ms)
+. x = 4  (walltime: 562188 ms)
+..* Value complete: x |-> y = (4|->2)  (walltime: 562188 ms)
+------
+Expression Value = 
+{(4|->2),(5|->1)}
+....
+
+With the external function <tt>TIME</tt> you can get the current time in seconds:
+....
+>>> TIME("sec")
+Expression Value = 
+11
+>>> TIME("now")
+Expression Value = 
+1581432376
+>>> TIME("now")
+Expression Value = 
+1581432377
+....
+
+With the external function <tt>DELTA_WALLTIME</tt> you can get the  time in milliseconds since the last call to <tt>DELTA_WALLTIME</tt>.
+
+== Performance Messages
+
+By setting the preference <tt>PERFORMANCE_INFO</tt> to <tt>TRUE</tt> ProB will print various performance messages.
+For example it may print messages when the evaluation of comprehension sets has exceeded a threshold. This threshold (in ms) can be influenced by setting the preference
+<tt>PERFORMANCE_INFO_LIMIT</tt>.
+
+== Debugging Constants Setup
+
+By setting the preference <tt>TRACE_INFO</tt> to <tt>TRUE</tt> ProB will print additional messages when evaluating certain predicates, in particular the <tt>PROPERTIES</tt> clause of a B machine.
+With this feature you can observe how constants get bound to values and can sometimes spot expensive predicates and large values.
+Some additional information about debugging the PROPERTIES can be found in the [[Tutorial Troubleshooting the Setup]].
+
+Let us take the following machine
+....
+MACHINE Debug
+CONSTANTS a,b,c
+PROPERTIES
+  a = card(b) &
+  b = %x.(x:1..c|x*x) &
+  c : 1000..1001 & c < 1001
+VARIABLES x
+INVARIANT x:NATURAL
+INITIALISATION x:=2
+OPERATIONS
+  Sqr = SELECT x:dom(b) THEN x := b(x) END;
+  Finished = SELECT x /: dom(b) THEN skip END
+END
+....
+
+Here is how we can debug the constants setup:
+
+....
+$ probcli Debug.mch -p TRACE_INFO TRUE -init
+% unused_constants(2,[a,c])
+nr_of_components(1)
+
+ ====> (1) c < 1001
+
+ ====> (1) a = card(b)
+
+ ====> (1) b = %x.(x : 1 .. c|x * x)
+
+ ====> (1) c : 1000 .. 1001
+finished_processing_component_predicates
+grounding_wait_flags
+ :?: a int(?:0..sup)
+ :?: b VARIABLE: _31319 : GRVAL-CHECK
+ :?: c int(?:inf..1000)
+--1-->> a
+     int(1000)
+--1-->> b
+     AVL.size=1000
+--1-->> c
+     int(1000)
+% Runtime for SOLUTION for SETUP_CONSTANTS: 107 ms (walltime: 110 ms)
+% Runtime to FINALISE SETUP_CONSTANTS: 0 ms (walltime: 0 ms)
+
+ =INIT=> x := 2
+ [=OK= 0 ms]
+....
+
+== Debugging Animation or Execution
+
+By using the <tt>-animate_stats</tt> flag, you can see execution times for operations that are executed either using the <tt>-execute</tt> or <tt>-animate</tt> commands.
+In verbose mode (<tt>-v</tt> flag) you also see the memory consumption.
+
+....
+$ probcli Debug.mch -execute_all -animate_stats
+% unused_constants(2,[a,c])
+% Runtime for SOLUTION for SETUP_CONSTANTS: 79 ms (walltime: 80 ms)
+1    : SETUP_CONSTANTS
+       91 ms walltime (89 ms runtime), since start: 1107 ms
+2    : INITIALISATION
+       5 ms walltime (4 ms runtime), since start: 1112 ms
+3    : Sqr
+       10 ms walltime (10 ms runtime), since start: 1123 ms
+4    : Sqr
+       0 ms walltime (0 ms runtime), since start: 1123 ms
+5    : Sqr
+       1 ms walltime (0 ms runtime), since start: 1124 ms
+6    : Sqr
+       0 ms walltime (0 ms runtime), since start: 1124 ms
+7    : Finished
+       3 ms walltime (4 ms runtime), since start: 1127 ms
+Infinite loop reached after 8 steps (looping on Finished).
+% Runtime for -execute: 116 ms (with gc: 116 ms, walltime: 119 ms); time since start: 1132 ms
+....
+
+== Profiling ==
+
+You can obtain some profiling information using the <tt>-prob_profile</tt> command.
+This command unfortunately requires that ProB was compiled using special flags (<tt>-Dprob_profile=true</tt> and <tt>-Dprob_src_profile=true</tt>).
+
+....
+$ probcli ../prob_examples/public_examples/B/Tutorial/Debug.mch -execute_all -prob_profile
+...
+--------------------------
+ProB profile info after 5685 ms walltime (5248 ms runtime)
+----Source Location Profiler Information----
+----Tracks number of times B statements (aka substitutions) are hit
+ 1 hits at 9:15 -- 9:19 in /Users/leuschel/git_root/prob_examples/public_examples/B/Tutorial/Debug.mch
+ 1 hits at 12:37 -- 12:41 in /Users/leuschel/git_root/prob_examples/public_examples/B/Tutorial/Debug.mch
+ 4 hits at 11:29 -- 11:38 in /Users/leuschel/git_root/prob_examples/public_examples/B/Tutorial/Debug.mch
+----
+---- ProB Runtime Profiler ----
+---- Tracks time spent in B operations and invariant evaluation
+ $setup_constants : 78 ms (80 ms walltime & 80 ms max. walltime; #calls 1)
+ Sqr : 9 ms (9 ms walltime & 9 ms max. walltime; #calls 1)
+ $initialise_machine : 5 ms (5 ms walltime & 5 ms max. walltime; #calls 1)
+ Finished : 3 ms (4 ms walltime & 4 ms max. walltime; #calls 1)
+ Total Walltime: 98 ms for #calls 4
+....
-- 
GitLab