To solve the given optimization problem, we first need to define the symbolic representation of the variables and then formulate the objective function and constraints accordingly.

Let's denote:
- $x_1$ as the number of units of essential oil used in the mixture.
- $x_2$ as the number of units of fruit scent used in the mixture.

The objective function aims to minimize the total cost of the mixture. Given that a unit of essential oil costs $3.50 and a unit of fruit scent costs $2, the objective function can be represented algebraically as:
\[ \text{Minimize: } 3.5x_1 + 2x_2 \]

The constraints based on the problem description are:
1. The mixture contains at least 6 units of aromatic notes: 
   - Since a unit of essential oil contains 3 units of aromatic notes and a unit of fruit scent contains 10 units, this constraint can be written as $3x_1 + 10x_2 \geq 6$.
2. The mixture lasts at least for 7 hours:
   - Given that a unit of essential oil lasts up to 9 hours and a unit of fruit scent lasts for 4 hours, we need to find a combination that satisfies the duration requirement. However, the problem doesn't specify how the durations combine. Assuming a linear combination (which might not perfectly model real-world behavior but follows typical LP formulations), this constraint could be represented as $9x_1 + 4x_2 \geq 7$.
3. The mixture can also contain at most 8 units of aromatic notes:
   - This constraint translates to $3x_1 + 10x_2 \leq 8$.

Thus, the symbolic representation of the problem is:

```json
{
  'sym_variables': [('x1', 'units of essential oil'), ('x2', 'units of fruit scent')],
  'objective_function': '3.5*x1 + 2*x2',
  'constraints': [
    '3*x1 + 10*x2 >= 6', 
    '9*x1 + 4*x2 >= 7', 
    '3*x1 + 10*x2 <= 8'
  ]
}
```

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

```python
from gurobipy import *

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

# Define variables
x1 = m.addVar(vtype=GRB.CONTINUOUS, name="essential_oil")
x2 = m.addVar(vtype=GRB.CONTINUOUS, name="fruit_scent")

# Set the objective function
m.setObjective(3.5*x1 + 2*x2, GRB.MINIMIZE)

# Add constraints
m.addConstr(3*x1 + 10*x2 >= 6, "aromatic_notes_min")
m.addConstr(9*x1 + 4*x2 >= 7, "duration_min")
m.addConstr(3*x1 + 10*x2 <= 8, "aromatic_notes_max")

# Optimize the model
m.optimize()

# Print the solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Essential Oil: {x1.x}")
    print(f"Fruit Scent: {x2.x}")
    print(f"Total Cost: {m.objVal}")
else:
    print("No optimal solution found")
```