Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Program::to_latex #381

Draft
wants to merge 83 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
7be2094
Initial ToLaTeX commit.
Feb 6, 2023
479974d
Add X and Y gate tests with helper function.
Feb 7, 2023
8fb30e5
Move gate tests to tests submodule gates.
Feb 7, 2023
cb02ef8
Add TikZ operators.
Feb 7, 2023
5cb096d
Add latex dependency as feature.
Feb 8, 2023
029d337
Rename TikzOperators to TikzOperator and CamelCase variant names.
Feb 8, 2023
c9fc7e9
Move latex.rs and snapshots into latex directory.
Feb 13, 2023
a25abb4
Initial commit for LaTeX abstract factory model.
Feb 16, 2023
1d418a4
Revert "Initial commit for LaTeX abstract factory model."
Feb 17, 2023
3f217f4
Remove new snapshot of failed X gate unit test.
Feb 17, 2023
ed1f8a0
Remove latex dependency and rename feature to-latex to latex.
Feb 17, 2023
e00633e
Add comments and update names wrt Quantikz docs.
Feb 22, 2023
b7642bc
Update snapshot test names.
Feb 22, 2023
865f495
Add document template and unit tests.
Feb 23, 2023
dc5b563
Add gate command and update command variant data types.
Feb 25, 2023
6486920
Add test for single qubit with two gates X and Y.
Feb 25, 2023
5cbfb4d
Build a Diagram from a vector of Circuits.
Feb 25, 2023
f3ea53b
Remove extraneous gate from snapshot test.
Feb 28, 2023
2a97404
Add LaTeX gen for single qubit gate instructions.
Feb 28, 2023
f39f1d8
Add multi-line n-qubit single qubit gates.
Feb 28, 2023
1a3d66c
Update doc string example for get_command.
Feb 28, 2023
6a4894d
Preserve order of wires by indexing circuit keys in vector.
Mar 1, 2023
04a1723
Add initial CNOT LaTeX gen for variable qubits.
Mar 1, 2023
458e750
Merge branch 'main' into to-latex
Mar 2, 2023
568fcdf
Add CNOT gate.
Mar 7, 2023
4a8cf9b
Add combined single and multi qubit gate tests.
Mar 7, 2023
e615f2c
Add settings test module with snapshot test.
Mar 7, 2023
8494931
Add impute missing qubits setting.
Mar 7, 2023
2048ccd
Debug CNOT with two TDD tests of complex Programs.
Mar 8, 2023
5094048
Optimize ctrl/targ programs with only one call to set_ctrl_targ.
Mar 8, 2023
dad6ac4
Allow CNOT for a single qubit.
Mar 8, 2023
423a7ec
Revert "Allow CNOT for a single qubit."
Mar 8, 2023
e36623a
Handle CNOT without target.
Mar 8, 2023
b2b1f1a
Working draft of CCNOT and CONTROLLED.
Mar 8, 2023
298075f
Revert "Allow CNOT for a single qubit."
Mar 8, 2023
9fc3c62
Merge with to-latex.
Mar 9, 2023
39f8f46
Add CONTROLLED and CCNOT.
Mar 9, 2023
b6a9e20
Update doc and remove unused variables.
Mar 9, 2023
6e1dfba
Reformat doc.
Mar 9, 2023
9062255
Reformat file.
Mar 9, 2023
6f3c0c3
Propagate LatexGenError instead of panic.
Mar 10, 2023
d40808e
Add PHASE, CZ, and CPHASE.
Mar 10, 2023
0cfb8d2
Initial docs.
Mar 10, 2023
6a20a52
Add DAGGER modifier.
Mar 11, 2023
5655d7e
Add texify numerical constants setting.
Mar 13, 2023
370c3cc
Fix get_symbol doctest.
Mar 13, 2023
5d9c138
Initial good modifiers test.
Mar 13, 2023
e49e7d7
Merge branch 'main' into to-latex
Mar 13, 2023
f0591fb
Merge branch 'to-latex' into good-tests
Mar 13, 2023
a068411
Add multiple controlled modifiers to single qubit gates.
Mar 13, 2023
86a280e
Add good defgate and modifiers tests.
Mar 14, 2023
2338b2e
Refactor to_latex with initial circuit of used qubits.
Mar 14, 2023
d31b231
Move to_latex code blocks to new functions and remove outdated TODOs.
Mar 15, 2023
6cd43dc
Test five good programs from quilc good-test-files.
Mar 15, 2023
5dfafec
Add error handling for unsupported programs.
Mar 15, 2023
772c2ad
Merge branch 'to-latex' into to-latex-docs
Mar 15, 2023
37dbb7f
Update docs including supported programs.
Mar 16, 2023
645b787
Tighten visibility of crate.
Mar 16, 2023
5d7940c
Fix docs and remove deadcode.
Mar 16, 2023
11cd5c5
Replace explicit Clone impl for Parameter with derived trait.
Mar 16, 2023
5dbaaad
Refactor get_symbol into ToString for Symbol and Parameter.
Mar 16, 2023
0b9213d
Apply docs suggestions from code review.
hiyaryan Mar 16, 2023
10fe4f3
Fix Quantikz link in documentation.
Mar 16, 2023
025f7fa
Add clippy fixes.
Mar 16, 2023
af07939
Apply clippy fixes, doc fixes, rename Settings to RenderSettings.
Mar 16, 2023
63e13ea
Add manual clippy fixes and Clone or Copy to structs and make more id…
Mar 17, 2023
3677651
Remove supported program checking.
Mar 17, 2023
6a2fd9e
Use write! in Diagram fmt, reduce/reformat docs.
Mar 20, 2023
6ec15be
Merge branch 'rigetti:main' into to-latex
hiyaryan Mar 20, 2023
28f16e7
Decompose gates to canonical form.
Mar 21, 2023
7ab4b5a
Fill circuit using instruction in canonical form.
Mar 22, 2023
e37d83e
Debug PHASE, multiline, and CNOT 0 0 tests.
Mar 22, 2023
61f990a
Handle unsupported instructions and gates.
Mar 22, 2023
1af1a9f
Update docs and readability.
Mar 22, 2023
029f05b
Refactor gate setting from parse_gate into separate method set_gate.
Mar 23, 2023
421e7eb
Rename feature to ToLatex, set_qw to set_empty, make enums more idiom…
Mar 23, 2023
cab0caf
Update doctest examples.
Mar 23, 2023
571c497
Rename err variant FoundCNOTWithNoTarget to FoundTargetWithNoControl.
Mar 23, 2023
fcf9215
WIP: refactor: LaTeX generation
kalzoo Mar 24, 2023
0b268ab
feat: don't display memory reference index if 0
kalzoo Mar 24, 2023
5a44377
feat: parse and display Gate directly
kalzoo Mar 24, 2023
eefbeba
Merge branch 'main' into feature/latex
kalzoo Jun 24, 2024
1e07548
chore: cleanup
kalzoo Jun 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
853 changes: 326 additions & 527 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions quil-rs/src/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,8 +1009,8 @@ mod tests {
#[test]
fn specific_round_trip_tests() {
for input in &[
"-1*(phases[0]+phases[1])",
"(-1*(phases[0]+phases[1]))+(-1*(phases[0]+phases[1]))",
"-1*(phases+phases[1])",
"(-1*(phases+phases[1]))+(-1*(phases+phases[1]))",
] {
let parsed = Expression::from_str(input);
let parsed = parsed.unwrap();
Expand Down
5 changes: 5 additions & 0 deletions quil-rs/src/instruction/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ impl Quil for MemoryReference {
f: &mut impl std::fmt::Write,
_fall_back_to_debug: bool,
) -> crate::quil::ToQuilResult<()> {
if self.index == 0 {
write!(f, "{}", self.name)?;
return Ok(());
}

write!(f, "{}[{}]", self.name, self.index).map_err(Into::into)
}
}
Expand Down
14 changes: 14 additions & 0 deletions quil-rs/src/instruction/gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ use crate::{
expression::Expression,
imag,
instruction::{write_expression_parameter_string, write_parameter_string, write_qubits, Qubit},
parser::{gate::parse_gate, lex, ParseError},
program::{disallow_leftover, SyntaxError},
quil::{write_join_quil, Quil},
real,
validation::identifier::{
validate_identifier, validate_user_identifier, IdentifierValidationError,
},
};
use ndarray::{array, linalg::kron, Array2};
use nom_locate::LocatedSpan;
use num_complex::Complex64;
use once_cell::sync::Lazy;
use std::{
cmp::Ordering,
collections::{HashMap, HashSet},
str::FromStr,
};

/// A struct encapsulating all the properties of a Quil Quantum Gate.
Expand Down Expand Up @@ -176,6 +180,16 @@ impl Gate {
}
}

impl FromStr for Gate {
type Err = SyntaxError<Self>;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let input = LocatedSpan::new(s);
let tokens = lex(input)?;
disallow_leftover(parse_gate(&tokens).map_err(ParseError::from_nom_internal_err))
}
}

/// Lift a unitary matrix to act on the specified qubits in a full `n_qubits`-qubit Hilbert
/// space.
///
Expand Down
1 change: 1 addition & 0 deletions quil-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
//! [constructor for timing graphs]: crate::program::graph::ScheduledProgram#method.get_dot_format
//! [expressions]: crate::expression::Expression
//! [instructions]: crate::instruction::Instruction
//! [latex]: crate::program::latex::Latex#method.to_latex
//! [parser]: crate::program::Program#method.from_str
//! [programs]: crate::program::Program
//! [serializer]: crate::program::Program#method.to_string
Expand Down
3 changes: 2 additions & 1 deletion quil-rs/src/parser/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ mod tests {
"%theta",
"cis(%theta)",
"%a+%b",
"(pi/2)+(1*theta[0])",
"(pi/2)+(1*theta)",
"(pi/2)+(1*theta[1])",
"3 - -2",
];

Expand Down
14 changes: 7 additions & 7 deletions quil-rs/src/parser/gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use nom::{combinator::opt, multi::many0, multi::separated_list0, sequence::delimited};

use crate::{instruction::Instruction, token};
use crate::token;

use super::{
common::{self, parse_gate_modifier},
Expand All @@ -25,7 +25,7 @@ use crate::instruction::Gate;
use crate::parser::InternalParserResult;

/// Parse a gate instruction.
pub(crate) fn parse_gate<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
pub(crate) fn parse_gate<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Gate> {
let (input, modifiers) = many0(parse_gate_modifier)(input)?;
let (input, name) = token!(Identifier(v))(input)?;
let (input, parameters) = opt(delimited(
Expand All @@ -37,32 +37,32 @@ pub(crate) fn parse_gate<'a>(input: ParserInput<'a>) -> InternalParserResult<'a,
let (input, qubits) = many0(common::parse_qubit)(input)?;
Ok((
input,
Instruction::Gate(Gate {
Gate {
name,
parameters,
qubits,
modifiers,
}),
},
))
}

#[cfg(test)]
mod test {
use super::parse_gate;
use crate::expression::Expression;
use crate::instruction::{Gate, GateModifier, Instruction, Qubit};
use crate::instruction::{Gate, GateModifier, Qubit};
use crate::make_test;
use crate::parser::lexer::lex;

make_test!(
test_modifiers,
parse_gate,
"DAGGER CONTROLLED RX(pi) 0 1",
Instruction::Gate(Gate {
Gate {
name: "RX".to_string(),
parameters: vec![Expression::PiConstant],
qubits: vec![Qubit::Fixed(0), Qubit::Fixed(1)],
modifiers: vec![GateModifier::Dagger, GateModifier::Controlled],
})
}
);
}
6 changes: 4 additions & 2 deletions quil-rs/src/parser/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

use nom::{
combinator::all_consuming,
combinator::{all_consuming, map},
multi::{many0, many1},
sequence::{delimited, preceded},
};
Expand Down Expand Up @@ -113,7 +113,9 @@ pub(crate) fn parse_instruction(input: ParserInput) -> InternalParserResult<Inst
},
_ => todo!(),
},
Some((Token::Identifier(_), _)) | Some((Token::Modifier(_), _)) => gate::parse_gate(input),
Some((Token::Identifier(_), _)) | Some((Token::Modifier(_), _)) => {
map(gate::parse_gate, Instruction::Gate)(input)
}
Some((_, _)) => Err(nom::Err::Failure(InternalParseError::from_kind(
&input[..1],
ParserErrorKind::NotACommandOrGate,
Expand Down
2 changes: 1 addition & 1 deletion quil-rs/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub(crate) use instruction::parse_instructions;
pub(crate) use lexer::lex;

mod command;
mod gate;
pub(crate) mod gate;
mod macros;

pub(crate) mod common;
Expand Down
Loading