Rebol3 Code Examplex
Functional coverage tree
A hierarchical model of verification coverage where cover groups and cover points are organized in a tree to track how thoroughly a design’s functionality has been exercised.
Rebol [
title: "Rosetta code: Functional coverage tree"
file: %Functional_coverage_tree.r3
url: https://rosettacode.org/wiki/Functional_coverage_tree
]
indent-to-tree: function [
"Converts indented text to a nested block tree"
text [string!]
/tab tab-size [integer!] "Indentation size (default: 4)"
][
tab-size: any [tab-size 4]
lines: split-lines text
stack: reduce [result: copy []]
depths: copy [0]
prev: 0
foreach line lines [
indent: tab-size
parse line [
any [#" " (++ indent) | #"^-" (indent: indent + tab-size)]
copy name: to end
]
if empty? name [continue]
level: indent // tab-size
if any [
not zero? indent % tab-size ;; catches non-multiple indentation
1 < (level - prev) ;; catches skipped levels
][
do make error! "Invalid indentation!"
]
prev: level
;; pop stack to current level
while [level < length? depths] [
take/last depths
take/last stack
]
node: reduce [name copy []]
append last stack node
append/only stack node/2
append depths level
]
result
]
;; -- Object prototype for an FC-node --
fc-node!: context [
name: ""
weight: 0
coverage: 0.0
children: []
parent: none
]
fcn-set-coverage: func [
n [object!]
value [decimal!]
][
if n/coverage <> value [
n/coverage: value
if n/parent [
fcn-update-coverage n/parent
]
]
]
fcn-update-coverage: func [n [object!]][
if empty? n/children [exit]
v1: v2: 0.0
foreach child n/children [
v1: v1 + (child/weight * child/coverage)
v2: v2 + child/weight
]
fcn-set-coverage n (v1 / v2)
]
fcn-show: func [n [object!] /indent level [integer!]][
indent: 4 * level: any [level 0]
printf reduce [
indent (32 - indent) "| " 6 " | " 8.000001 " |"
][ SP n/name n/weight n/coverage]
foreach child n/children [
fcn-show/indent child level + 1
]
]
build-tree: function [
data [block! string!]
parent [none! object!]
][
if string? data [data: indent-to-tree data]
parent: any [parent make fc-node! []]
foreach [line children] data [
val: split line #"|"
node: make fc-node! [
name: trim/tail val/1
weight: any [attempt [transcode/one val/2] 1 ]
coverage: any [attempt [transcode/one val/3] 0.0]
children: copy []
parent: none
]
node/parent: parent
append parent/children node
build-tree children node
]
fcn-update-coverage parent
parent
]
root: build-tree {
cleaning | | |
house1 |40 | |
bedrooms | |0.25 |
bathrooms | | |
bathroom1 | |0.5 |
bathroom2 | | |
outside_lavatory | |1 |
attic | |0.75 |
kitchen | |0.1 |
living_rooms | | |
lounge | | |
dining_room | | |
conservatory | | |
playroom | |1 |
basement | | |
garage | | |
garden | |0.8 |
house2 |60 | |
upstairs | | |
bedrooms | | |
suite_1 | | |
suite_2 | | |
bedroom_3 | | |
bedroom_4 | | |
bathroom | | |
toilet | | |
attics | |0.6 |
groundfloor | | |
kitchen | | |
living_rooms | | |
lounge | | |
dining_room | | |
conservatory | | |
playroom | | |
wet_room_&_toilet | | |
garage | | |
garden | |0.9 |
hot_tub_suite | |1 |
basement | | |
cellars | |1 |
wine_cellar | |1 |
cinema | |0.75 |} none
cleaning: root/children/1
top-coverage: cleaning/coverage
print ["TOP COVERAGE =" top-coverage newline]
print "NAME HIERARCHY | WEIGHT | COVERAGE |"
fcn-show cleaning
cinema: cleaning/children/2/children/3/children/3
fcn-set-coverage cinema 1.0
print rejoin [
"^/If the coverage of the Cinema node were increased from 0.75 to 1^/"
"the top level coverage would increase by "
round/to cleaning/coverage - top-coverage 0.000001
" to " round/to cleaning/coverage 0.000001
]
Output:
TOP COVERAGE = 0.409166666666667
NAME HIERARCHY | WEIGHT | COVERAGE |
cleaning | 1 | 0.409167 |
house1 | 40 | 0.33125 |
bedrooms | 1 | 0.25 |
bathrooms | 1 | 0.5 |
bathroom1 | 1 | 0.5 |
bathroom2 | 1 | 0.0 |
outside_lavatory | 1 | 1.0 |
attic | 1 | 0.75 |
kitchen | 1 | 0.1 |
living_rooms | 1 | 0.25 |
lounge | 1 | 0.0 |
dining_room | 1 | 0.0 |
conservatory | 1 | 0.0 |
playroom | 1 | 1.0 |
basement | 1 | 0.0 |
garage | 1 | 0.0 |
garden | 1 | 0.8 |
house2 | 60 | 0.461111 |
upstairs | 1 | 0.15 |
bedrooms | 1 | 0.0 |
suite_1 | 1 | 0.0 |
suite_2 | 1 | 0.0 |
bedroom_3 | 1 | 0.0 |
bedroom_4 | 1 | 0.0 |
bathroom | 1 | 0.0 |
toilet | 1 | 0.0 |
attics | 1 | 0.6 |
groundfloor | 1 | 0.316667 |
kitchen | 1 | 0.0 |
living_rooms | 1 | 0.0 |
lounge | 1 | 0.0 |
dining_room | 1 | 0.0 |
conservatory | 1 | 0.0 |
playroom | 1 | 0.0 |
wet_room_&_toilet | 1 | 0.0 |
garage | 1 | 0.0 |
garden | 1 | 0.9 |
hot_tub_suite | 1 | 1.0 |
basement | 1 | 0.916667 |
cellars | 1 | 1.0 |
wine_cellar | 1 | 1.0 |
cinema | 1 | 0.75 |
If the coverage of the Cinema node were increased from 0.75 to 1
the top level coverage would increase by 0.016667 to 0.425833