## Symbolic Representation of the Optimization Problem

The optimization problem can be symbolically represented as follows:

```json
{
    'sym_variables': [
        ('x1', 'regular ice cream'),
        ('x2', 'premium ice cream')
    ],
    'objective_function': '1*x1 + 2.5*x2',
    'constraints': [
        'x1 <= 40',
        'x2 <= 25',
        'x1 + x2 <= 60',
        'x1 >= 0',
        'x2 >= 0'
    ]
}
```

## Gurobi Code for the Optimization Problem

To solve this linear programming optimization problem using Gurobi, we can use the following Python code:

```python
import gurobi

def solve_ice_cream_problem():
    # Create a new Gurobi model
    model = gurobi.Model()

    # Define the variables
    x1 = model.addVar(lb=0, name="regular_ice_cream")
    x2 = model.addVar(lb=0, name="premium_ice_cream")

    # Set the objective function
    model.setObjective(1*x1 + 2.5*x2, gurobi.GRB.MAXIMIZE)

    # Add constraints
    model.addConstr(x1 <= 40, name="regular_demand_constraint")
    model.addConstr(x2 <= 25, name="premium_demand_constraint")
    model.addConstr(x1 + x2 <= 60, name="total_production_constraint")

    # Optimize the model
    model.optimize()

    # Check if the model is optimized
    if model.status == gurobi.GRB.OPTIMAL:
        print("Optimal solution found.")
        print(f"Regular ice cream: {x1.varValue}")
        print(f"Premium ice cream: {x2.varValue}")
        print(f"Maximum profit: {model.objVal}")
    else:
        print("No optimal solution found.")

# Run the function
solve_ice_cream_problem()
```

This code defines a Gurobi model with two variables, `x1` and `x2`, representing the number of regular and premium ice creams to produce, respectively. The objective function is set to maximize the profit, which is $1*x1 + 2.5*x2$. The constraints are added to ensure that the demand for regular and premium ice creams is not exceeded and that the total production does not exceed 60 ice creams. The model is then optimized, and the optimal solution is printed if found.