LLZK 3.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
SMTInfoOps.cpp
Go to the documentation of this file.
1//===-- SMTInfoOps.cpp - SMT script metadata operations ---------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2026 Project LLZK
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
11
12#include "SMTInfoDetail.h"
13
14#include <mlir/IR/Builders.h>
15
16#include <llvm/ADT/StringExtras.h>
17#include <llvm/ADT/TypeSwitch.h>
18
19#define GET_OP_CLASSES
21
22using namespace mlir;
23using namespace llzk::smt_info;
24
25namespace {
26
27static bool isSetInfoValue(Attribute attr) {
28 return TypeSwitch<Attribute, bool>(attr)
29 .Case<BoolAttr, IntegerAttr, StringAttr, KeywordAttr, SymbolAttr>([](auto) { return true; })
30 .Case<ArrayAttr>([](ArrayAttr values) {
31 return llvm::all_of(values, isSetInfoValue);
32 }).Default([](Attribute) { return false; });
33}
34
35static void printValue(AsmPrinter &printer, Attribute value) {
36 TypeSwitch<Attribute>(value)
37 .Case<KeywordAttr, SymbolAttr>([&](auto attr) { printer << attr.getValue(); })
38 .Case<StringAttr, BoolAttr>([&](auto attr) { printer.printAttribute(attr); })
39 .Case<IntegerAttr>([&](auto attr) {
40 SmallString<32> text;
41 attr.getValue().toStringSigned(text);
42 printer << text;
43 }).Case<ArrayAttr>([&](ArrayAttr values) {
44 printer << '(';
45 llvm::interleave(values, [&](Attribute attr) { printValue(printer, attr); }, [&] {
46 printer << ' ';
47 });
48 printer << ')';
49 });
50}
51
52static ParseResult parseValue(OpAsmParser &parser, Attribute &value) {
53 Builder builder(parser.getContext());
54 if (succeeded(parser.parseOptionalLParen())) {
55 SmallVector<Attribute> values;
56 while (failed(parser.parseOptionalRParen())) {
57 Attribute element;
58 if (parseValue(parser, element)) {
59 return failure();
60 }
61 values.push_back(element);
62 }
63 value = builder.getArrayAttr(values);
64 return success();
65 }
66 if (succeeded(parser.parseOptionalColon())) {
67 StringRef keyword;
68 if (parser.parseKeyword(&keyword)) {
69 return failure();
70 }
71 value = llzk::smt_info::detail::getKeywordAttr(parser.getContext(), (":" + keyword).str());
72 return success();
73 }
74 APInt number;
75 if (auto parsed = parser.parseOptionalInteger(number); parsed.has_value()) {
76 if (failed(*parsed)) {
77 return failure();
78 }
79 value = IntegerAttr::get(IntegerType::get(parser.getContext(), number.getBitWidth()), number);
80 return success();
81 }
82 StringAttr string;
83 if (auto parsed = parser.parseOptionalAttribute(string, Type()); parsed.has_value()) {
84 if (failed(*parsed)) {
85 return failure();
86 }
87 value = string;
88 return success();
89 }
90 StringRef symbol;
91 if (succeeded(parser.parseOptionalKeyword(&symbol))) {
92 value = symbol == "true" || symbol == "false"
93 ? Attribute(builder.getBoolAttr(symbol == "true"))
94 : llzk::smt_info::detail::getSymbolAttr(parser.getContext(), symbol);
95 return success();
96 }
97 return parser.emitError(parser.getCurrentLocation()) << "expected SMT-LIB set-info value";
98}
99
100} // namespace
101
102ParseResult SMTInfoSetOp::parse(OpAsmParser &parser, OperationState &result) {
103 SMLoc loc = parser.getCurrentLocation();
104 StringAttr key;
105 Attribute value;
106 if (parser.parseAttribute(key) || parseValue(parser, value) ||
107 parser.parseOptionalAttrDict(result.attributes)) {
108 return failure();
109 }
111 return parser.emitError(loc);
112 }, key.getValue()))) {
113 return failure();
114 }
115 result.addAttribute(
116 "key", llzk::smt_info::detail::getKeywordAttr(parser.getContext(), key.getValue())
117 );
118 result.addAttribute("value", value);
119 result.location = parser.getEncodedSourceLoc(loc);
120 return success();
121}
122
123void SMTInfoSetOp::print(OpAsmPrinter &printer) {
124 printer << ' ';
125 printer.printAttribute(StringAttr::get(getContext(), getKey().getValue()));
126 printer << ' ';
127 printValue(printer, getValueAttr());
128 printer.printOptionalAttrDict((*this)->getAttrs(), {"key", "value"});
129}
130
131LogicalResult SMTInfoSetOp::verify() {
132 if (!isSetInfoValue(getValueAttr())) {
133 return emitOpError(
134 "requires an SMT-LIB set-info value built from strings, booleans, integers, SMT keywords, "
135 "SMT symbols, or nested lists"
136 );
137 }
138 return success();
139}
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
::mlir::Attribute getValueAttr()
void print(::mlir::OpAsmPrinter &p)
::llvm::LogicalResult verify()
::llzk::smt_info::KeywordAttr getKey()
mlir::Attribute getSymbolAttr(mlir::MLIRContext *context, llvm::StringRef value)
Creates a symbol attribute without exposing generated attribute storage to operation implementation f...
mlir::Attribute getKeywordAttr(mlir::MLIRContext *context, llvm::StringRef value)
Creates a keyword attribute without exposing generated attribute storage to operation implementation ...
mlir::LogicalResult verifyKeyword(llvm::function_ref< mlir::InFlightDiagnostic()> emitError, llvm::StringRef value)
Verifies that value is a valid SMT-LIB keyword and reports failures through emitError.