diff --git a/src/Simulation/Core/Argument.cs b/src/Simulation/Core/Argument.cs
new file mode 100644
index 00000000000..b7ef2efbff5
--- /dev/null
+++ b/src/Simulation/Core/Argument.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#nullable enable
+
+namespace Microsoft.Quantum.Runtime
+{
+ ///
+ /// An argument to a QIR callable.
+ ///
+ public class Argument
+ {
+ ///
+ /// The name of the argument.
+ ///
+ public string Name { get; }
+
+ ///
+ /// The value of the argument.
+ ///
+ public ArgumentValue Value { get; }
+
+ ///
+ /// Creates a new argument.
+ ///
+ /// The name of the argument.
+ /// The value of the argument.
+ public Argument(string name, ArgumentValue value) => (this.Name, this.Value) = (name, value);
+ }
+}
diff --git a/src/Simulation/Core/ArgumentType.cs b/src/Simulation/Core/ArgumentType.cs
new file mode 100644
index 00000000000..7dc2db55f22
--- /dev/null
+++ b/src/Simulation/Core/ArgumentType.cs
@@ -0,0 +1,73 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#nullable enable
+
+namespace Microsoft.Quantum.Runtime
+{
+ ///
+ /// The type of an argument to a QIR callable.
+ ///
+ public class ArgumentType
+ {
+ private ArgumentType()
+ {
+ }
+
+ ///
+ /// The boolean type.
+ ///
+ public static ArgumentType Bool { get; } = new ArgumentType();
+
+ ///
+ /// The integer type.
+ ///
+ public static ArgumentType Int { get; } = new ArgumentType();
+
+ ///
+ /// The double-precision floating point type.
+ ///
+ public static ArgumentType Double { get; } = new ArgumentType();
+
+ ///
+ /// The Pauli operator type.
+ ///
+ public static ArgumentType Pauli { get; } = new ArgumentType();
+
+ ///
+ /// The range type.
+ ///
+ public static ArgumentType Range { get; } = new ArgumentType();
+
+ ///
+ /// The result type.
+ ///
+ public static ArgumentType Result { get; } = new ArgumentType();
+
+ ///
+ /// The string type.
+ ///
+ public static ArgumentType String { get; } = new ArgumentType();
+
+ ///
+ /// The array type.
+ ///
+ public class Array : ArgumentType
+ {
+ ///
+ /// The type of the array items.
+ ///
+ public ArgumentType Item { get; }
+
+ ///
+ /// Creates a new array type.
+ ///
+ /// The type of the array items.
+ public Array(ArgumentType item) => this.Item = item;
+
+ public override bool Equals(object obj) => obj is Array array && this.Item.Equals(array.Item);
+
+ public override int GetHashCode() => this.Item.GetHashCode() + 1;
+ }
+ }
+}
diff --git a/src/Simulation/Core/ArgumentValue.cs b/src/Simulation/Core/ArgumentValue.cs
new file mode 100644
index 00000000000..8f9c713b29b
--- /dev/null
+++ b/src/Simulation/Core/ArgumentValue.cs
@@ -0,0 +1,185 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#nullable enable
+
+using System.Collections.Immutable;
+using System.Linq;
+using Microsoft.Quantum.Simulation.Core;
+using Core = Microsoft.Quantum.Simulation.Core;
+
+namespace Microsoft.Quantum.Runtime
+{
+ ///
+ /// The value of an argument to a QIR callable is a discriminated union of the argument types.
+ ///
+ public abstract class ArgumentValue
+ {
+ ///
+ /// The type of the argument.
+ ///
+ public abstract ArgumentType Type { get; }
+
+ private ArgumentValue()
+ {
+ }
+
+ ///
+ /// A boolean argument value.
+ ///
+ public class Bool : ArgumentValue
+ {
+ ///
+ /// The value of the argument.
+ ///
+ public bool Value { get; }
+
+ public override ArgumentType Type => ArgumentType.Bool;
+
+ ///
+ /// Creates a boolean argument value.
+ ///
+ /// The value of the argument.
+ public Bool(bool value) => this.Value = value;
+ }
+
+ ///
+ /// An integer argument value.
+ ///
+ public class Int : ArgumentValue
+ {
+ ///
+ /// The value of the argument.
+ ///
+ public long Value { get; }
+
+ public override ArgumentType Type => ArgumentType.Int;
+
+ ///
+ /// Creates an integer argument value.
+ ///
+ /// The value of the argument.
+ public Int(long value) => this.Value = value;
+ }
+
+ ///
+ /// A double-precision floating point argument value.
+ ///
+ public class Double : ArgumentValue
+ {
+ ///
+ /// The value of the argument.
+ ///
+ public double Value { get; }
+
+ public override ArgumentType Type => ArgumentType.Double;
+
+ ///
+ /// Creates a double-precision floating point argument value.
+ ///
+ /// The value of the argument.
+ public Double(double value) => this.Value = value;
+ }
+
+ ///
+ /// A Pauli operator argument value.
+ ///
+ public class Pauli : ArgumentValue
+ {
+ ///
+ /// The value of the argument.
+ ///
+ public Core.Pauli Value { get; }
+
+ public override ArgumentType Type => ArgumentType.Pauli;
+
+ ///
+ /// Creates a Pauli operator argument value.
+ ///
+ /// The value of the argument.
+ public Pauli(Core.Pauli value) => this.Value = value;
+ }
+
+ ///
+ /// A range argument value.
+ ///
+ public class Range : ArgumentValue
+ {
+ ///
+ /// The value of the argument.
+ ///
+ public QRange Value { get; }
+
+ public override ArgumentType Type => ArgumentType.Range;
+
+ ///
+ /// Creates a range argument value.
+ ///
+ /// The value of the argument.
+ public Range(QRange value) => this.Value = value;
+ }
+
+ ///
+ /// A result argument value.
+ ///
+ public class Result : ArgumentValue
+ {
+ ///
+ /// The value of the argument.
+ ///
+ public Core.Result Value { get; }
+
+ public override ArgumentType Type => ArgumentType.Result;
+
+ ///
+ /// Creates a result argument value.
+ ///
+ /// The value of the argument.
+ public Result(Core.Result value) => this.Value = value;
+ }
+
+ ///
+ /// A string argument value.
+ ///
+ public class String : ArgumentValue
+ {
+ ///
+ /// The value of the argument.
+ ///
+ public string Value { get; }
+
+ public override ArgumentType Type => ArgumentType.String;
+
+ ///
+ /// Creates a string argument value.
+ ///
+ /// The value of the argument.
+ public String(string value) => this.Value = value;
+ }
+
+ ///
+ /// An array argument value where all values are of the same type.
+ ///
+ public class Array : ArgumentValue
+ {
+ ///
+ /// The values of the argument.
+ ///
+ public ImmutableArray Values { get; }
+
+ public override ArgumentType Type { get; }
+
+ private Array(ImmutableArray values, ArgumentType itemType) =>
+ (this.Values, this.Type) = (values, new ArgumentType.Array(itemType));
+
+ ///
+ /// Tries to create an array argument value.
+ ///
+ /// The values of the argument.
+ /// The type of the values.
+ /// The array or null if not all values have the type .
+ public static Array? TryCreate(ImmutableArray values, ArgumentType itemType) =>
+ values.All(value => value.Type.Equals(itemType)) ? new Array(values, itemType) : null;
+ }
+ }
+}
diff --git a/src/Simulation/Core/Microsoft.Quantum.Runtime.Core.csproj b/src/Simulation/Core/Microsoft.Quantum.Runtime.Core.csproj
index b5169a63955..866adc91ba0 100644
--- a/src/Simulation/Core/Microsoft.Quantum.Runtime.Core.csproj
+++ b/src/Simulation/Core/Microsoft.Quantum.Runtime.Core.csproj
@@ -18,6 +18,7 @@
+
diff --git a/src/Simulation/Core/Submitters/IAzureSubmitter.cs b/src/Simulation/Core/Submitters/IAzureSubmitter.cs
new file mode 100644
index 00000000000..0fc11515b3f
--- /dev/null
+++ b/src/Simulation/Core/Submitters/IAzureSubmitter.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#nullable enable
+
+namespace Microsoft.Quantum.Runtime
+{
+ ///
+ /// An interface for submitting quantum programs to Azure.
+ ///
+ public interface IAzureSubmitter
+ {
+ ///
+ /// The ID of the quantum machine provider.
+ ///
+ string ProviderId { get; }
+
+ ///
+ /// The name of the target quantum machine. A provider may expose multiple targets that can be used to execute
+ /// programs. Users may select which target they would like to be used for execution.
+ ///
+ string Target { get; }
+ }
+}
diff --git a/src/Simulation/Core/Submitters/IQirSubmitter.cs b/src/Simulation/Core/Submitters/IQirSubmitter.cs
new file mode 100644
index 00000000000..f18c171c6f0
--- /dev/null
+++ b/src/Simulation/Core/Submitters/IQirSubmitter.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#nullable enable
+
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+
+namespace Microsoft.Quantum.Runtime
+{
+ ///
+ /// An interface for submitting QIR programs to Azure.
+ ///
+ public interface IQirSubmitter : IAzureSubmitter
+ {
+ ///
+ /// Submits a job to execute a QIR program without waiting for execution to complete.
+ ///
+ /// The QIR program as a byte stream.
+ /// The fully-qualified name of the entry point to execute.
+ /// The arguments to the entry point in the order in which they are declared.
+ /// The submitted job.
+ Task SubmitAsync(Stream qir, string entryPoint, IReadOnlyList arguments);
+ }
+}
diff --git a/src/Simulation/Core/Submitters/IQuantumMachine.cs b/src/Simulation/Core/Submitters/IQuantumMachine.cs
index 0e7cc236692..361a6eea37a 100644
--- a/src/Simulation/Core/Submitters/IQuantumMachine.cs
+++ b/src/Simulation/Core/Submitters/IQuantumMachine.cs
@@ -7,28 +7,15 @@
namespace Microsoft.Quantum.Runtime
{
///
- /// Interface that a quantum machine must implement.
+ /// An interface for submitting Q# programs to Azure.
///
- public interface IQuantumMachine
+ public interface IQuantumMachine : IAzureSubmitter
{
-
///
/// Function that configures a job object before submission.
///
public delegate void ConfigureJob(object job);
- ///
- /// Gets the ID of the quantum machine provider.
- ///
- string ProviderId { get; }
-
- ///
- /// Gets the name of the target quantum machine.
- /// A provider may expose multiple targets that can be used to execute programs.
- /// Users may select which target they would like to be used for execution.
- ///
- string Target { get; }
-
///
/// Executes a Q# program.
/// Submits a job to execute it and continuously checks whether it has been completed.