1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use clingo::*;
use std::env;
fn print_prefix(depth: u8) {
println!();
for _ in 0..depth {
print!(" ");
}
}
// recursively print the statistics object
fn print_statistics(stats: &Statistics, key: u64, depth: u8) {
// get the type of an entry and switch over its various values
let statistics_type = stats.statistics_type(key).unwrap();
match statistics_type {
// print values
StatisticsType::Value => {
let value = stats
.value_get(key)
.expect("Failed to retrieve statistics value.");
print!(" {}", value);
}
// print arrays
StatisticsType::Array => {
// loop over array elements
let size = stats
.array_size(key)
.expect("Failed to retrieve statistics array size.");
for i in 0..size {
// print array offset (with prefix for readability)
let subkey = stats
.array_at(key, i)
.expect("Failed to retrieve statistics array.");
print_prefix(depth);
print!("{} zu:", i);
// recursively print subentry
print_statistics(stats, subkey, depth + 1);
}
}
// print maps
StatisticsType::Map => {
// loop over map elements
let size = stats.map_size(key).unwrap();
for i in 0..size {
// get and print map name (with prefix for readability)
let name = stats.map_subkey_name(key, i).unwrap();
let subkey = stats.map_at(key, name).unwrap();
print_prefix(depth);
print!("{}:", name);
// recursively print subentry
print_statistics(stats, subkey, depth + 1);
}
}
// this case won't occur if the statistics are traversed like this
StatisticsType::Empty => {
println!("StatisticsType::Empty");
}
}
}
fn print_model(model: &Model) {
// retrieve the symbols in the model
let atoms = model
.symbols(ShowType::SHOWN)
.expect("Failed to retrieve symbols in the model.");
print!("Model:");
for symbol in atoms {
print!(" {}", symbol);
}
println!();
}
fn solve(ctl: Control) -> Control {
// get a solve handle
let mut handle = ctl
.solve(SolveMode::YIELD, &[])
.expect("Failed retrieving solve handle.");
// loop over all models
loop {
handle.resume().expect("Failed resume on solve handle.");
match handle.model() {
// print the model
Ok(Some(model)) => print_model(model),
// stop if there are no more models
Ok(None) => break,
Err(e) => panic!("Error: {}", e),
}
}
// close the solve handle
handle
.get()
.expect("Failed to get result from solve handle.");
handle.close().expect("Failed to close solve handle.")
}
fn main() {
// collect clingo options from the command line
let options = env::args().skip(1).collect();
// create a control object and pass command line arguments
let mut ctl = control(options).expect("Failed creating Control.");
{
// get the configuration object and its root key
let conf = ctl.configuration_mut().unwrap();
let root_key = conf.root().unwrap();
// and set the statistics level to one to get more statistics
let subkey = conf.map_at(root_key, "stats").unwrap();
conf.value_set(subkey, "1")
.expect("Failed to set value in configuration.");
}
// add a logic program to the base part
ctl.add("base", &[], "a :- not b. b :- not a.").unwrap();
// ground the base part
let part = Part::new("base", vec![]).unwrap();
let parts = vec![part];
ctl.ground(&parts).unwrap();
// solve
let ctl = solve(ctl);
// get the statistics object, get the root key, then print the statistics recursively
let stats = ctl.statistics().unwrap();
let stats_key = stats.root().unwrap();
print_statistics(stats, stats_key, 0);
}