## Symbolic Representation

The problem can be converted into a symbolic representation as follows:

- **Variables:**
  - $x_1$ = acres of oranges
  - $x_2$ = acres of grapefruits

- **Objective Function:** Maximize $200x_1 + 220x_2$

- **Constraints:**
  1. $x_1 + x_2 \leq 200$ (total acres of land)
  2. $x_1 \geq 60$ (minimum acres of oranges)
  3. $x_2 \geq 50$ (minimum acres of grapefruits)
  4. $x_2 \leq 2x_1$ (at most twice the amount of grapefruits as oranges)
  5. $x_1, x_2 \geq 0$ (non-negativity constraint, though implicitly satisfied by constraints 2 and 3)

## JSON Representation

```json
{
  'sym_variables': [('x1', 'acres of oranges'), ('x2', 'acres of grapefruits')],
  'objective_function': '200*x1 + 220*x2',
  'constraints': [
    'x1 + x2 <= 200',
    'x1 >= 60',
    'x2 >= 50',
    'x2 <= 2*x1'
  ]
}
```

## Gurobi Code

```python
import gurobi

def solve_farmer_problem():
    # Create a new model
    m = gurobi.Model()

    # Define variables
    x1 = m.addVar(lb=0, name="oranges")  # acres of oranges
    x2 = m.addVar(lb=0, name="grapefruits")  # acres of grapefruits

    # Objective function: Maximize profit
    m.setObjective(200 * x1 + 220 * x2, gurobi.GRB.MAXIMIZE)

    # Constraints
    m.addConstr(x1 + x2 <= 200, name="total_land")
    m.addConstr(x1 >= 60, name="min_oranges")
    m.addConstr(x2 >= 50, name="min_grapefruits")
    m.addConstr(x2 <= 2 * x1, name="grapefruits_vs_oranges")

    # Update model
    m.update()

    # Solve model
    m.optimize()

    # Print solution
    if m.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal acres of oranges: {x1.varValue}")
        print(f"Optimal acres of grapefruits: {x2.varValue}")
        print(f"Max Profit: ${200 * x1.varValue + 220 * x2.varValue}")
    else:
        print("The model is infeasible")

solve_farmer_problem()
```