Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Closed
16 changes: 16 additions & 0 deletions src/Simulation/Core/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ public static Result ToResult(this bool b)
: Result.Zero;
}

public static Result ToResult(this bool b, Qubit qubit)
{
return b
? new ResultMeasured(ResultValue.One, qubit)
: new ResultMeasured(ResultValue.Zero, qubit);
}

public static Result ToResult(this uint b)
{
Debug.Assert(b == 0 || b == 1, $"Unexpected result value: {b}");
Expand All @@ -33,6 +40,15 @@ public static Result ToResult(this uint b)
: Result.One;
}

public static Result ToResult(this uint b, Qubit qubit)
{
Debug.Assert(b == 0 || b == 1, $"Unexpected result value: {b}");

return b == 0
? new ResultMeasured(ResultValue.Zero, qubit)
: new ResultMeasured(ResultValue.One, qubit);
}

public static double Pow(this double x, double y)
{
return System.Math.Pow(x, y);
Expand Down
11 changes: 8 additions & 3 deletions src/Simulation/Core/RuntimeMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,16 @@ public class RuntimeMetadata
/// <summary>
/// True if operation is composed of multiple operations.
/// </summary>
/// </summary>
/// <remarks>
/// This is used in composite operations, such as <c>ApplyToEach</c>.
/// </remarks>
public bool IsComposite { get; set; }

/// <summary>
/// True if operation is a classically-controlled conditional operation.
/// </summary>
public bool IsConditional { get; set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I like this name/description for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the name not descriptive enough or is it the description that is not clear?
This flag is true when the operation is an If-Else statement, like ApplyIfElseR and will contain 2 Children (one for each measurement value).


/// <summary>
/// Group of operations for each classical branch (<c>true</c> and <c>false</c>).
/// </summary>
Expand Down Expand Up @@ -83,7 +87,8 @@ public override bool Equals(object? obj)

if (this.Label != other.Label || this.FormattedNonQubitArgs != other.FormattedNonQubitArgs ||
this.IsAdjoint != other.IsAdjoint || this.IsControlled != other.IsControlled ||
this.IsMeasurement != other.IsMeasurement || this.IsComposite != other.IsComposite)
this.IsMeasurement != other.IsMeasurement || this.IsComposite != other.IsComposite ||
this.IsConditional != other.IsConditional)
return false;

if (!ListEquals<Qubit>(this.Controls, other.Controls)) return false;
Expand Down Expand Up @@ -122,7 +127,7 @@ public override int GetHashCode()

// Combine all other properties and get the resulting hashcode
var otherHash = HashCode.Combine(this.Label, this.FormattedNonQubitArgs, this.IsAdjoint, this.IsControlled,
this.IsMeasurement, this.IsComposite);
this.IsMeasurement, this.IsComposite, this.IsConditional);

// Combine them all together to get the final hashcode
return HashCode.Combine(controlsHash, targetsHash, childrenHash, otherHash);
Expand Down
18 changes: 18 additions & 0 deletions src/Simulation/Core/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,24 @@ public override ResultValue GetValue()
}
}

public class ResultMeasured : Result
{
private ResultValue Value;

public Qubit Qubit { get; set; }

public ResultMeasured(ResultValue value, Qubit qubit)
{
Value = value;
Qubit = qubit;
}

public override ResultValue GetValue()
{
return Value;
}
}

/// <summary>
/// Represents the Result of a Measurement. Corresponds to Q# type <code>Result</code>.
/// </summary>
Expand Down
95 changes: 95 additions & 0 deletions src/Simulation/QsharpCore/ClassicalControl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#nullable enable

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Quantum.Simulation.Core;

namespace Microsoft.Quantum.Simulation.QuantumProcessor.Extensions
{
/// <summary>
/// Provides interface to access base `GetRuntimeMetadata` method.
/// </summary>
public interface IApplyIfElse : ICallable
{
RuntimeMetadata? GetBaseRuntimeMetadata(IApplyData args);
}

/// <summary>
/// Provides static `GetRuntimeMetadata` method for ApplyIfElseR and its variants
/// to avoid code duplication.
/// </summary>
public class ApplyIfElseUtils<__C__, __T__, __U__>
{
public static RuntimeMetadata? GetRuntimeMetadata(IApplyIfElse op, IApplyData args)
{
Debug.Assert(args.Value is ValueTuple<Result, (__C__, __T__), (__C__, __U__)>,
$"Failed to retrieve runtime metadata for {op.ToString()}.");

if (args.Value is ValueTuple<Result, (__C__, __T__), (__C__, __U__)> ifArgs)
{
var (result, (onZeroOp, zeroArg), (onOneOp, oneArg)) = ifArgs;
var metadata = op.GetBaseRuntimeMetadata(args);

if (metadata == null) return null;

if (result is ResultMeasured measured)
{
metadata.IsConditional = true;
metadata.Controls = new List<Qubit>() { measured.Qubit };
}
else
{
metadata.IsComposite = true;
}

return metadata;
}

return null;
}
}

public partial class ApplyIfElseR<__T__, __U__> : IApplyIfElse
{
public RuntimeMetadata? GetBaseRuntimeMetadata(IApplyData args) =>
base.GetRuntimeMetadata(args);

/// <inheritdoc/>
public override RuntimeMetadata? GetRuntimeMetadata(IApplyData args) =>
ApplyIfElseUtils<ICallable, __T__, __U__>.GetRuntimeMetadata(this, args);
}

public partial class ApplyIfElseRA<__T__, __U__> : IApplyIfElse
{
public RuntimeMetadata? GetBaseRuntimeMetadata(IApplyData args) =>
base.GetRuntimeMetadata(args);

/// <inheritdoc/>
public override RuntimeMetadata? GetRuntimeMetadata(IApplyData args) =>
ApplyIfElseUtils<IAdjointable, __T__, __U__>.GetRuntimeMetadata(this, args);
}

public partial class ApplyIfElseRC<__T__, __U__> : IApplyIfElse
{
public RuntimeMetadata? GetBaseRuntimeMetadata(IApplyData args) =>
base.GetRuntimeMetadata(args);

/// <inheritdoc/>
public override RuntimeMetadata? GetRuntimeMetadata(IApplyData args) =>
ApplyIfElseUtils<IControllable, __T__, __U__>.GetRuntimeMetadata(this, args);
}

public partial class ApplyIfElseRCA<__T__, __U__> : IApplyIfElse
{
public RuntimeMetadata? GetBaseRuntimeMetadata(IApplyData args) =>
base.GetRuntimeMetadata(args);

/// <inheritdoc/>
public override RuntimeMetadata? GetRuntimeMetadata(IApplyData args) =>
ApplyIfElseUtils<IUnitary, __T__, __U__>.GetRuntimeMetadata(this, args);
}
}
Loading