or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

behavioral-analysis.mdcli-tools.mdcontract-system.mdindex.mdsymbolic-execution.md

symbolic-execution.mddocs/

0

# Symbolic Execution Engine

1

2

CrossHair's symbolic execution engine provides the core functionality for creating and manipulating symbolic values, managing execution state, and performing symbolic reasoning. This system enables the tool to explore execution paths and find counterexamples automatically.

3

4

## Capabilities

5

6

### Value Realization

7

8

Convert symbolic values to concrete representations for inspection and debugging.

9

10

```python { .api }

11

def realize(value):

12

"""

13

Convert symbolic values to concrete values.

14

15

Parameters:

16

- value: Any symbolic or concrete value

17

18

Returns:

19

Concrete representation of the value

20

"""

21

22

def deep_realize(value, memo=None):

23

"""

24

Deeply convert symbolic values using copy mechanism.

25

26

Parameters:

27

- value: Value to realize

28

- memo: Optional memoization dictionary to handle circular references

29

30

Returns:

31

Deeply realized value with all nested symbolic values converted

32

"""

33

```

34

35

**Usage Example:**

36

37

```python

38

from crosshair import realize, deep_realize

39

40

# Realize a simple symbolic value

41

concrete_val = realize(symbolic_int)

42

43

# Deep realization for complex nested structures

44

complex_data = {"items": [symbolic_list], "metadata": symbolic_dict}

45

concrete_data = deep_realize(complex_data)

46

```

47

48

### Symbolic Value Creation

49

50

Create symbolic values for different Python types to enable symbolic execution.

51

52

```python { .api }

53

class SymbolicFactory:

54

"""

55

Factory for creating symbolic values of various types.

56

57

The SymbolicFactory is the primary interface for creating symbolic values

58

during symbolic execution. It maintains the connection to the StateSpace

59

and handles type-specific symbolic value creation.

60

"""

61

62

def __init__(self, space, pytype, varname):

63

"""

64

Initialize symbolic factory.

65

66

Parameters:

67

- space: StateSpace instance managing solver state

68

- pytype: Python type for the factory

69

- varname: Base variable name for created symbols

70

"""

71

72

def __call__(self, typ, suffix="", allow_subtypes=True):

73

"""

74

Create symbolic value of given type.

75

76

Parameters:

77

- typ: Type to create symbolic value for

78

- suffix: Optional suffix for variable name uniqueness

79

- allow_subtypes: Whether to allow subtypes of the specified type

80

81

Returns:

82

Symbolic value of the specified type

83

"""

84

85

def get_suffixed_varname(self, suffix):

86

"""

87

Get unique variable name with suffix.

88

89

Parameters:

90

- suffix: Suffix to append

91

92

Returns:

93

Unique variable name string

94

"""

95

```

96

97

**Usage Example:**

98

99

```python

100

from crosshair import SymbolicFactory, StateSpace

101

102

# Create a symbolic factory

103

space = StateSpace(deadline, timeout, root)

104

factory = SymbolicFactory(space, int, "x")

105

106

# Create symbolic integers

107

sym_int1 = factory(int)

108

sym_int2 = factory(int, suffix="alt")

109

110

# Create symbolic values for custom types

111

sym_custom = factory(MyCustomClass, allow_subtypes=False)

112

```

113

114

### Execution State Management

115

116

Manage SMT solver state and execution branching during symbolic execution.

117

118

```python { .api }

119

class StateSpace:

120

"""

121

Holds SMT solver state and execution information.

122

123

StateSpace manages the Z3 SMT solver instance, tracks execution branches,

124

handles constraint solving, and provides utilities for symbolic execution.

125

"""

126

127

def __init__(self, execution_deadline, model_check_timeout, search_root):

128

"""

129

Initialize state space.

130

131

Parameters:

132

- execution_deadline: Maximum execution time

133

- model_check_timeout: Timeout for SMT solver queries

134

- search_root: Root node for execution tree

135

"""

136

137

def add(self, expr):

138

"""

139

Add constraint to solver.

140

141

Parameters:

142

- expr: Z3 expression to add as constraint

143

"""

144

145

def fork_parallel(self, false_probability, desc=""):

146

"""

147

Create execution fork with specified probability.

148

149

Parameters:

150

- false_probability: Probability of taking false branch (0.0-1.0)

151

- desc: Optional description for debugging

152

153

Returns:

154

Boolean indicating which branch was taken

155

"""

156

157

def is_possible(self, expr):

158

"""

159

Check if expression could be true given current constraints.

160

161

Parameters:

162

- expr: Z3 expression to check

163

164

Returns:

165

True if expression is satisfiable, False otherwise

166

"""

167

168

def choose_possible(self, expr_choices):

169

"""

170

Choose from possible expressions based on satisfiability.

171

172

Parameters:

173

- expr_choices: List of Z3 expressions to choose from

174

175

Returns:

176

First satisfiable expression from the list

177

"""

178

179

def find_model_value(self, expr):

180

"""

181

Find model value for SMT expression.

182

183

Parameters:

184

- expr: Z3 expression to find value for

185

186

Returns:

187

Concrete value satisfying the expression in current model

188

"""

189

190

def smt_fork(self, expr):

191

"""

192

Fork execution based on SMT expression.

193

194

Parameters:

195

- expr: Z3 boolean expression to fork on

196

197

Returns:

198

Boolean indicating which branch (true/false) was taken

199

"""

200

201

def defer_assumption(self, description, checker):

202

"""

203

Defer assumption checking until later in execution.

204

205

Parameters:

206

- description: Human-readable description of assumption

207

- checker: Callable that returns boolean for assumption validity

208

"""

209

210

def rand(self):

211

"""

212

Get random number generator.

213

214

Returns:

215

Random.Random instance for this execution path

216

"""

217

218

def extra(self, typ):

219

"""

220

Get extra data of specified type.

221

222

Parameters:

223

- typ: Type of extra data to retrieve

224

225

Returns:

226

Extra data instance of specified type

227

"""

228

229

def uniq(self):

230

"""

231

Get unique identifier.

232

233

Returns:

234

Unique integer identifier for this state space

235

"""

236

```

237

238

**Usage Example:**

239

240

```python

241

from crosshair import StateSpace

242

import z3

243

244

# Create state space

245

space = StateSpace(deadline=30.0, timeout=5.0, root=None)

246

247

# Add constraints

248

x = z3.Int('x')

249

space.add(x > 0)

250

space.add(x < 100)

251

252

# Check possibilities

253

if space.is_possible(x == 50):

254

print("x could be 50")

255

256

# Fork execution

257

if space.smt_fork(x > 50):

258

# Handle x > 50 case

259

print("Exploring x > 50")

260

else:

261

# Handle x <= 50 case

262

print("Exploring x <= 50")

263

```

264

265

### Function Patching and Registration

266

267

Register patches and custom symbolic types for extending symbolic execution capabilities.

268

269

```python { .api }

270

def register_patch(entity, patch_value):

271

"""

272

Register a patch for a callable.

273

274

Parameters:

275

- entity: Callable to patch

276

- patch_value: Replacement callable to use during symbolic execution

277

"""

278

279

def register_type(typ, creator):

280

"""

281

Register custom symbolic value creator for a type.

282

283

Parameters:

284

- typ: Type to register creator for

285

- creator: Callback function that creates symbolic values of this type

286

"""

287

288

def with_realized_args(fn, deep=False):

289

"""

290

Decorator that realizes function arguments before calling.

291

292

Parameters:

293

- fn: Function to wrap

294

- deep: Whether to perform deep realization of arguments

295

296

Returns:

297

Wrapped function that realizes arguments before execution

298

"""

299

300

class patch_to_return:

301

"""

302

Context manager for patching functions to return specific values.

303

304

Allows temporary patching of functions during symbolic execution

305

to control their return values for testing purposes.

306

"""

307

308

def __init__(self, return_values):

309

"""

310

Initialize patch context.

311

312

Parameters:

313

- return_values: Dict mapping callables to lists of return values

314

"""

315

316

def __enter__(self):

317

"""Enter patch context."""

318

319

def __exit__(self, *args):

320

"""Exit patch context and restore original functions."""

321

```

322

323

**Usage Example:**

324

325

```python

326

from crosshair import register_patch, register_type, with_realized_args, patch_to_return

327

328

# Register a patch for a function

329

def mock_database_call():

330

return "mocked_result"

331

332

register_patch(real_database_call, mock_database_call)

333

334

# Register custom type creator

335

def create_symbolic_custom_type(space, typ, varname):

336

# Return symbolic instance of custom type

337

return SymbolicCustomType(varname)

338

339

register_type(MyCustomType, create_symbolic_custom_type)

340

341

# Use argument realization decorator

342

@with_realized_args

343

def debug_function(x, y):

344

print(f"Called with concrete values: {x}, {y}")

345

return x + y

346

347

# Temporary function patching

348

with patch_to_return({expensive_function: [42, 100, -1]}):

349

# expensive_function will return 42, then 100, then -1 on successive calls

350

result1 = expensive_function() # Returns 42

351

result2 = expensive_function() # Returns 100

352

```

353

354

### Tracing Control

355

356

Control symbolic execution tracing for performance and debugging.

357

358

```python { .api }

359

def NoTracing():

360

"""

361

Context manager to disable tracing.

362

363

Returns:

364

Context manager that disables CrossHair's execution tracing

365

"""

366

367

def ResumedTracing():

368

"""

369

Context manager to resume tracing.

370

371

Returns:

372

Context manager that re-enables CrossHair's execution tracing

373

"""

374

375

def is_tracing():

376

"""

377

Check if currently tracing.

378

379

Returns:

380

True if tracing is currently enabled, False otherwise

381

"""

382

```

383

384

**Usage Example:**

385

386

```python

387

from crosshair import NoTracing, ResumedTracing, is_tracing

388

389

# Disable tracing for performance-critical sections

390

with NoTracing():

391

# This code runs without CrossHair tracing overhead

392

result = expensive_computation()

393

394

# Resume tracing when needed

395

with ResumedTracing():

396

# This code runs with full tracing enabled

397

analyzed_result = analyze_result(result)

398

399

# Check tracing status

400

if is_tracing():

401

print("Tracing is active")

402

```

403

404

### Utility Functions

405

406

Additional utilities for type handling and debugging during symbolic execution.

407

408

```python { .api }

409

def python_type(obj):

410

"""

411

Get the Python type of an object, handling symbolic objects.

412

413

Parameters:

414

- obj: Object to get type of

415

416

Returns:

417

Python type, properly handling symbolic value types

418

419

For symbolic objects with __ch_pytype__ method, returns the actual

420

Python type being symbolically represented rather than the symbolic

421

wrapper type. Raises CrossHairInternal if called while tracing.

422

"""

423

424

def normalize_pytype(typ):

425

"""

426

Normalize type annotations for symbolic execution.

427

428

Parameters:

429

- typ: Type to normalize

430

431

Returns:

432

Normalized type suitable for symbolic execution

433

434

Handles TypeVar bounds (converting to bound type or object),

435

converts Any to object, and handles other type system complexities

436

to produce types suitable for symbolic value creation.

437

"""

438

439

def debug(*args):

440

"""

441

Print debugging information in CrossHair's nested log output.

442

443

Parameters:

444

- *args: Arguments to print for debugging

445

"""

446

```

447

448

**Usage Example:**

449

450

```python

451

from crosshair import python_type, normalize_pytype, debug

452

453

# Get type of symbolic values

454

sym_val = create_symbolic_int()

455

actual_type = python_type(sym_val) # Returns int, not symbolic wrapper type

456

457

# Normalize complex type annotations

458

from typing import List, Optional

459

normalized = normalize_pytype(Optional[List[int]])

460

461

# Debug symbolic execution

462

debug("Current symbolic value:", sym_val, "Type:", actual_type)

463

```