To solve Jack's production scheduling problem, we first need to define the decision variables and the constraints based on the given information.

Let's denote:
- \(R\) as the number of rings produced.
- \(N\) as the number of necklaces produced.

The profit from selling a ring is $50, and from selling a necklace is $75. Thus, the total profit can be represented as \(50R + 75N\).

The constraints are based on the availability of the machines:
1. The heating machine is available for at most 15 hours. Since it takes 1 hour to make a ring and 3 hours to make a necklace, we have: \(R + 3N \leq 15\).
2. The polishing machine is available for at most 12 hours. Given that it takes 2 hours to polish a ring and 4 hours to polish a necklace, we get: \(2R + 4N \leq 12\).

Additionally, Jack cannot produce a negative number of rings or necklaces, so we also have:
- \(R \geq 0\)
- \(N \geq 0\)

Now, let's formulate this problem in Gurobi using Python:

```python
from gurobipy import *

# Create a new model
m = Model("Production_Scheduling")

# Define the decision variables
R = m.addVar(vtype=GRB.INTEGER, name="Rings", lb=0)
N = m.addVar(vtype=GRB.INTEGER, name="Necklaces", lb=0)

# Set the objective function: Maximize profit
m.setObjective(50*R + 75*N, GRB.MAXIMIZE)

# Add constraints
m.addConstr(R + 3*N <= 15, "Heating_Machine_Constraint")
m.addConstr(2*R + 4*N <= 12, "Polishing_Machine_Constraint")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Number of Rings: {R.x}")
    print(f"Number of Necklaces: {N.x}")
    print(f"Total Profit: ${50*R.x + 75*N.x:.2f}")
else:
    print("No optimal solution found")
```