```json
{
  "sym_variables": [
    ("x1", "investment in company M"),
    ("x2", "investment in company P")
  ],
  "objective_function": "0.09x1 + 0.12x2",
  "constraints": [
    "x1 + x2 <= 100000",
    "x1 >= 3x2",
    "x1 <= 80000",
    "x1 >= 0",
    "x2 >= 0"
  ]
}
```

```python
import gurobipy as gp
from gurobipy import GRB

# Create a new model
m = gp.Model("vaccine_investment")

# Create variables
investment_M = m.addVar(name="investment_M")
investment_P = m.addVar(name="investment_P")

# Set objective function
m.setObjective(0.09 * investment_M + 0.12 * investment_P, GRB.MAXIMIZE)

# Add constraints
m.addConstr(investment_M + investment_P <= 100000, "total_investment")
m.addConstr(investment_M >= 3 * investment_P, "M_vs_P")
m.addConstr(investment_M <= 80000, "max_M")
m.addConstr(investment_M >= 0, "non_neg_M")  # Ensure non-negative investments
m.addConstr(investment_P >= 0, "non_neg_P")

# Optimize model
m.optimize()

# Check for infeasibility
if m.status == GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    # Print optimal solution
    print(f"Optimal investment in company M: {investment_M.x}")
    print(f"Optimal investment in company P: {investment_P.x}")
    print(f"Maximum earnings: {m.objVal}")

```
