Skip to content

Commit

Permalink
Added support for up to 10 circuit outputs.
Browse files Browse the repository at this point in the history
commit-id:29d3ea61
  • Loading branch information
orizi committed Jun 13, 2024
1 parent 88f0506 commit 68572f2
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 3 deletions.
32 changes: 30 additions & 2 deletions corelib/src/circuit.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,36 @@ trait CircuitDefinition<CES> {
/// The circuit internal type for a tuple of `CircuitElement`s.
type CircuitType;
}
impl CircuitDefinition1<Out0> of CircuitDefinition<(CircuitElement<Out0>,)> {
type CircuitType = Circuit<(Out0,)>;
impl CircuitDefinitionImpl<
T, impl Unwrap: UnwrapCircuitElement<T>, +core::metaprogramming::IsTuple<T>
> of CircuitDefinition<T> {
type CircuitType = Circuit<Unwrap::Unwrapped>;
}

/// Helper trait to get the unwrapped type of a `CircuitElement`, as well as the tuple of unwrapped
/// types from a tuple of `CircuitElement`s.
trait UnwrapCircuitElement<T> {
type Unwrapped;
}
/// Implementation for unwrapping a single `CircuitElement`.
impl UnwrapCircuitElementDirect<T> of UnwrapCircuitElement<CircuitElement<T>> {
type Unwrapped = T;
}
/// Implementation for unwrapping a basic tuple of `CircuitElement`s.
impl UnwrapCircuitElementBase<
T, impl UnwrapT: UnwrapCircuitElement<T>
> of UnwrapCircuitElement<(T,)> {
type Unwrapped = (UnwrapT::Unwrapped,);
}
/// Implementation for unwrapping a tuple of `CircuitElement`s.
impl UnwrapCircuitElementNext<
T,
impl TS: core::metaprogramming::TupleSplit<T>,
impl UnwrapHead: UnwrapCircuitElement<TS::Head>,
impl UnwrapRest: UnwrapCircuitElement<TS::Rest>,
impl TEF: core::metaprogramming::TupleExtendFront<UnwrapRest::Unwrapped, UnwrapHead::Unwrapped>,
> of UnwrapCircuitElement<T> {
type Unwrapped = TEF::Target;
}

/// A trait for setting up instances of a circuit defined using `CircuitElement`s.
Expand Down
165 changes: 165 additions & 0 deletions corelib/src/metaprogramming.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,171 @@ impl TupleSplitFixedSizedArraySized10<T> of TupleSplit<[T; 10]> {
}
}

/// A trait for extending a tuple from the front.
pub(crate) trait TupleExtendFront<T, E> {
/// The type of the resulting tuple.
type Target;
/// Creates a new tuple from the `value` tuple with `element` in front of it.
fn extend_front(value: T, element: E) -> Self::Target nopanic;
}
impl TupleExtendFrontTupleSize0<E> of TupleExtendFront<(), E> {
type Target = (E,);
fn extend_front(value: (), element: E) -> (E,) nopanic {
(element,)
}
}
impl TupleExtendFrontTupleSize1<E0, E> of TupleExtendFront<(E0,), E> {
type Target = (E, E0);
fn extend_front(value: (E0,), element: E) -> (E, E0) nopanic {
let (e0,) = value;
(element, e0)
}
}
impl TupleExtendFrontTupleSize2<E0, E1, E> of TupleExtendFront<(E0, E1), E> {
type Target = (E, E0, E1);
fn extend_front(value: (E0, E1), element: E) -> (E, E0, E1) nopanic {
let (e0, e1) = value;
(element, e0, e1)
}
}
impl TupleExtendFrontTupleSize3<E0, E1, E2, E> of TupleExtendFront<(E0, E1, E2), E> {
type Target = (E, E0, E1, E2);
fn extend_front(value: (E0, E1, E2), element: E) -> (E, E0, E1, E2) nopanic {
let (e0, e1, e2) = value;
(element, e0, e1, e2)
}
}
impl TupleExtendFrontTupleSize4<E0, E1, E2, E3, E> of TupleExtendFront<(E0, E1, E2, E3), E> {
type Target = (E, E0, E1, E2, E3);
fn extend_front(value: (E0, E1, E2, E3), element: E) -> (E, E0, E1, E2, E3) nopanic {
let (e0, e1, e2, e3) = value;
(element, e0, e1, e2, e3)
}
}
impl TupleExtendFrontTupleSize5<
E0, E1, E2, E3, E4, E
> of TupleExtendFront<(E0, E1, E2, E3, E4), E> {
type Target = (E, E0, E1, E2, E3, E4);
fn extend_front(value: (E0, E1, E2, E3, E4), element: E) -> (E, E0, E1, E2, E3, E4) nopanic {
let (e0, e1, e2, e3, e4) = value;
(element, e0, e1, e2, e3, e4)
}
}
impl TupleExtendFrontTupleSize6<
E0, E1, E2, E3, E4, E5, E
> of TupleExtendFront<(E0, E1, E2, E3, E4, E5), E> {
type Target = (E, E0, E1, E2, E3, E4, E5);
fn extend_front(
value: (E0, E1, E2, E3, E4, E5), element: E
) -> (E, E0, E1, E2, E3, E4, E5) nopanic {
let (e0, e1, e2, e3, e4, e5) = value;
(element, e0, e1, e2, e3, e4, e5)
}
}
impl TupleExtendFrontTupleSize7<
E0, E1, E2, E3, E4, E5, E6, E
> of TupleExtendFront<(E0, E1, E2, E3, E4, E5, E6), E> {
type Target = (E, E0, E1, E2, E3, E4, E5, E6);
fn extend_front(
value: (E0, E1, E2, E3, E4, E5, E6), element: E
) -> (E, E0, E1, E2, E3, E4, E5, E6) nopanic {
let (e0, e1, e2, e3, e4, e5, e6) = value;
(element, e0, e1, e2, e3, e4, e5, e6)
}
}
impl TupleExtendFrontTupleSize8<
E0, E1, E2, E3, E4, E5, E6, E7, E
> of TupleExtendFront<(E0, E1, E2, E3, E4, E5, E6, E7), E> {
type Target = (E, E0, E1, E2, E3, E4, E5, E6, E7);
fn extend_front(
value: (E0, E1, E2, E3, E4, E5, E6, E7), element: E
) -> (E, E0, E1, E2, E3, E4, E5, E6, E7) nopanic {
let (e0, e1, e2, e3, e4, e5, e6, e7) = value;
(element, e0, e1, e2, e3, e4, e5, e6, e7)
}
}
impl TupleExtendFrontTupleSize9<
E0, E1, E2, E3, E4, E5, E6, E7, E8, E
> of TupleExtendFront<(E0, E1, E2, E3, E4, E5, E6, E7, E8), E> {
type Target = (E, E0, E1, E2, E3, E4, E5, E6, E7, E8);
fn extend_front(
value: (E0, E1, E2, E3, E4, E5, E6, E7, E8), element: E
) -> (E, E0, E1, E2, E3, E4, E5, E6, E7, E8) nopanic {
let (e0, e1, e2, e3, e4, e5, e6, e7, e8) = value;
(element, e0, e1, e2, e3, e4, e5, e6, e7, e8)
}
}
impl TupleExtendFrontFixedSizedArraySize0<T> of TupleExtendFront<[T; 0], T> {
type Target = [T; 1];
fn extend_front(value: [T; 0], element: T) -> [T; 1] nopanic {
let [] = value;
[element]
}
}
impl TupleExtendFrontFixedSizedArraySize1<T> of TupleExtendFront<[T; 1], T> {
type Target = [T; 2];
fn extend_front(value: [T; 1], element: T) -> [T; 2] nopanic {
let [e0] = value;
[element, e0]
}
}
impl TupleExtendFrontFixedSizedArraySize2<T> of TupleExtendFront<[T; 2], T> {
type Target = [T; 3];
fn extend_front(value: [T; 2], element: T) -> [T; 3] nopanic {
let [e0, e1] = value;
[element, e0, e1]
}
}
impl TupleExtendFrontFixedSizedArraySize3<T> of TupleExtendFront<[T; 3], T> {
type Target = [T; 4];
fn extend_front(value: [T; 3], element: T) -> [T; 4] nopanic {
let [e0, e1, e2] = value;
[element, e0, e1, e2]
}
}
impl TupleExtendFrontFixedSizedArraySize4<T> of TupleExtendFront<[T; 4], T> {
type Target = [T; 5];
fn extend_front(value: [T; 4], element: T) -> [T; 5] nopanic {
let [e0, e1, e2, e3] = value;
[element, e0, e1, e2, e3]
}
}
impl TupleExtendFrontFixedSizedArraySize5<T> of TupleExtendFront<[T; 5], T> {
type Target = [T; 6];
fn extend_front(value: [T; 5], element: T) -> [T; 6] nopanic {
let [e0, e1, e2, e3, e4] = value;
[element, e0, e1, e2, e3, e4]
}
}
impl TupleExtendFrontFixedSizedArraySize6<T> of TupleExtendFront<[T; 6], T> {
type Target = [T; 7];
fn extend_front(value: [T; 6], element: T) -> [T; 7] nopanic {
let [e0, e1, e2, e3, e4, e5] = value;
[element, e0, e1, e2, e3, e4, e5]
}
}
impl TupleExtendFrontFixedSizedArraySize7<T> of TupleExtendFront<[T; 7], T> {
type Target = [T; 8];
fn extend_front(value: [T; 7], element: T) -> [T; 8] nopanic {
let [e0, e1, e2, e3, e4, e5, e6] = value;
[element, e0, e1, e2, e3, e4, e5, e6]
}
}
impl TupleExtendFrontFixedSizedArraySize8<T> of TupleExtendFront<[T; 8], T> {
type Target = [T; 9];
fn extend_front(value: [T; 8], element: T) -> [T; 9] nopanic {
let [e0, e1, e2, e3, e4, e5, e6, e7] = value;
[element, e0, e1, e2, e3, e4, e5, e6, e7]
}
}
impl TupleExtendFrontFixedSizedArraySize9<T> of TupleExtendFront<[T; 9], T> {
type Target = [T; 10];
fn extend_front(value: [T; 9], element: T) -> [T; 10] nopanic {
let [e0, e1, e2, e3, e4, e5, e6, e7, e8] = value;
[element, e0, e1, e2, e3, e4, e5, e6, e7, e8]
}
}

/// A trait for forwarding a wrapping snapshot from a tuple style struct into a tuple style struct
/// of the snapshots.
pub(crate) trait TupleSnapForward<T> {
Expand Down
7 changes: 6 additions & 1 deletion corelib/src/test/circuit_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ fn test_circuit_success() {

let modulus = TryInto::<_, CircuitModulus>::try_into([7, 0, 0, 0]).unwrap();
let outputs =
match (mul,).new_inputs().next([3, 0, 0, 0]).next([6, 0, 0, 0]).done().eval(modulus) {
match (mul, add, inv)
.new_inputs()
.next([3, 0, 0, 0])
.next([6, 0, 0, 0])
.done()
.eval(modulus) {
EvalCircuitResult::Success(outputs) => { outputs },
EvalCircuitResult::Failure((_, _)) => { panic!("Expected success") }
};
Expand Down

0 comments on commit 68572f2

Please sign in to comment.