To tackle this optimization problem, we first need to translate the natural language description into a symbolic representation. This involves defining variables and formulating the objective function along with the constraints.

Let's denote:
- \(x_1\) as the number of heated rooms.
- \(x_2\) as the number of unheated rooms.

The objective is to maximize profit. Given that the profit per heated room is $50 and the profit per unheated room is $35, the objective function can be written as:
\[ \text{Maximize:} \quad 50x_1 + 35x_2 \]

Now, let's formulate the constraints based on the problem description:
1. The hostel has 40 rooms available in total.
   - \(x_1 + x_2 \leq 40\)
2. At least 15 rooms must be heated.
   - \(x_1 \geq 15\)
3. At least 4 times as many people prefer unheated rooms to heated rooms.
   - \(x_2 \geq 4x_1\)

Additionally, since we cannot have negative rooms, both \(x_1\) and \(x_2\) should be non-negative:
- \(x_1 \geq 0\)
- \(x_2 \geq 0\)

And, because the number of rooms must be an integer (you can't have a fraction of a room), both \(x_1\) and \(x_2\) are integers.

Now, let's put this into the requested format for clarity:

```json
{
  'sym_variables': [('x1', 'number of heated rooms'), ('x2', 'number of unheated rooms')],
  'objective_function': '50*x1 + 35*x2',
  'constraints': [
    'x1 + x2 <= 40',
    'x1 >= 15',
    'x2 >= 4*x1',
    'x1 >= 0',
    'x2 >= 0'
  ]
}
```

To solve this problem using Gurobi in Python, we can write the following code:

```python
from gurobipy import *

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

# Define variables
x1 = m.addVar(vtype=GRB.INTEGER, name="heated_rooms")
x2 = m.addVar(vtype=GRB.INTEGER, name="unheated_rooms")

# Set objective function
m.setObjective(50*x1 + 35*x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(x1 + x2 <= 40, "total_rooms")
m.addConstr(x1 >= 15, "min_heated_rooms")
m.addConstr(x2 >= 4*x1, "unheated_vs_heated")
m.addConstr(x1 >= 0, "non_negative_heated")
m.addConstr(x2 >= 0, "non_negative_unheated")

# Optimize model
m.optimize()

# Print solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Heated rooms: {x1.x}")
    print(f"Unheated rooms: {x2.x}")
    print(f"Maximum profit: {m.objVal}")
else:
    print("No optimal solution found")
```